腾讯《后台&综合-第一次笔试》题解

一共五道题,做不完,做了四道,有一道没时间了。

字符串压缩解压:

普通模拟,用栈存下来左括号,每次遇到一个右括号,就把中间的字符串分析一遍,解压
string s;
struct p{
    int l;
    int r;
    p(int a,int b){
        l = a;
        r = b;
    }
};
stack<int> kuo;

int main(){

    cin>>s;
    int n = s.size();
    for(int i=0;i<n;++i){

        if(s[i] == '['){
            kuo.push(i);
        }
        if(s[i] == ']'){
            int t = kuo.top();
            kuo.pop();
            string a = s.substr(t+1, i-t-1);

            bool flag = 0;
            int num = 0;
            string str;
            for(int j=0;j<a.size();++j){
                if(!flag && isdigit(a[j])){
                    num+=a[j]-'0';
                    num*=10;
                }
                else if(a[j] == '|'){
                    flag = true;
                    str = a.substr(j+1, n-j-1);
                    break;
                }
            }
            num/=10;
            string replace;
            for(int j=0;j<num;++j){
                replace +=  str;
            }
            s = s.substr(0,t)+ replace + s.substr(i+1, n-i-1);
            n = s.size();
            i = t+replace.size()-1;

        }
    }
    cout<<s<<endl;
}

放多少个xxx可以覆盖整条河面  最小区间覆盖问题

先按照左值排序,然后右值倒叙


struct p{
    int l;
    int r;
    bool operator<(const p & a)const{
        if(l == a.l) return r>a.r;
        return l<a.l;
    }
} arg[100005];

int main(){
    cin>>n>>l;
    for(int i=0;i<n;++i){
        cin>>arg[i].l>>arg[i].r;
    }
    sort(arg, arg+n);
    if(arg[0].l>0){
        cout<<-1<<endl;
        return 0;
    }
    int right = 0, pos = 0, max_len = 0;
    int ans=0;
    while(true){
        if(right >= l){
            break;
        }
        for(int i=pos;i<n;++i){
            if(arg[i].l<=right && arg[i].r > max_len){
                pos = i;
                max_len = arg[i].r;
            }
            if(arg[i].l>right){
                break;
            }
        }
        if(max_len == right){
            cout<<-1<<endl;
            return 0;
        }
        right = max_len;
        ++ans;
    }

    cout<<ans<<endl;

}

反转区间之后问还有多少逆序对,没时间写。。。

前提条件,对于一个个数位n的数组,正序对个数+逆序对个数 = 总对数= n*(n-1)

大概可能的思路是,归并排序的同时计算逆序对个数,计算到正好是我们需要翻转的那一层,记下一个个数k。
最后算出总的逆序对个数ans之后,之前算的那部分逆序对正好是完全算错的, ans  -  2^(m-n)*(2^n*(2^n-1))  +  2*k,中间部分为所有的对数,

看得到多少楼

预处理左边能看到的楼。右边能看到的楼,总的看到的数量是左边可以看到的楼+右边可以看到的楼+1
预处理使用栈,如果发现现在需要入栈的楼比栈顶高了,就将它出栈。直到可以放进去位置,此时可以看到的楼的数量为栈的总大小

int n;
int w[100005];
int l[100005],r[100005];

stack<int> stk;

int main(){
    cin>>n;
    for(int i=0;i<n;++i){
        cin>>w[i];
    }
    for(int i=0;i<n;++i){
        if(stk.empty()){
            stk.push(w[i]);
        }
        else{
            while(!stk.empty() && stk.top()<=w[i]){
                stk.pop();
            }
            stk.push(w[i]);
        }
        l[i] = stk.size();
    }

    while(!stk.empty()) stk.pop();

    for(int i=n-1;i>=0;--i){
        if(stk.empty()){
            stk.push(w[i]);
        }
        else{
            while(!stk.empty() && stk.top()<=w[i]){
                stk.pop();
            }
            stk.push(w[i]);
        }
        r[i] = stk.size();
    }

    for(int i=0;i<n;++i){
        int ans = 1;
        if(i>0){
            ans+=l[i-1];
        }
        if(i<n-1){
            ans+=r[i+1];
        }
        cout<<ans<<" ";
    }cout<<endl;

}


最少可以休息几天

动态规划,分成三种情况,0上班,1运动,2休息,如果目前这个情况不合法,那么设置为-1
int dp[100005][3];
int seq[100005][2];
int n;
// 0 work 1 sport 2 rest

int main(){
    cin>>n;
    for(int t = 0;t<2;++t) {
        for (int i = 0; i < n; ++i) {
            cin >> seq[i][t];
        }
    }
    dp[0][0] = (seq[0][0] == 1) ? 0:-1;
    dp[0][1] = (seq[0][1] == 1) ? 0:-1;
    dp[0][2] = 1;
    for(int i=1;i<n;++i){
        if(seq[i][0]) {// want work
            dp[i][0] = min(dp[i-1][1], dp[i-1][2]);
            if(dp[i][0] == -1){
                dp[i][0] = dp[i-1][2];
            }
        }
        else{
            dp[i][0] = -1;
        }
        if(seq[i][1]) {// want work
            dp[i][1] = min(dp[i-1][0], dp[i-1][2]);
            if(dp[i][1] == -1){
                dp[i][1] = dp[i-1][2];
            }
        }
        else{
            dp[i][1] = -1;
        }
        int m = 99999999;
        if(seq[i-1][0]){
            m = min(m,dp[i-1][0]);
        }
        if(seq[i-1][1]){
            m = min(m,dp[i-1][1]);
        }
        m = min(dp[i-1][2]+1, m+1);
        dp[i][2] = m;

    }

    // 最后在dp[n-1][0],dp[n-1][1],dp[n-1][2]之中选出最小的不为-1【合法】的结果

}



#腾讯##题解##笔试题目#
全部评论
请问楼主投的什么岗位...我投的测试也考这个现在有点慌😥
点赞 回复 分享
发布于 2019-09-18 14:44

相关推荐

贺兰星辰:不要漏个人信息,除了简历模板不太好以外你这个个人简介是不是太夸大了...
点赞 评论 收藏
分享
重生2012之我是java程序员:换个稍微正式点的照片吧
点赞 评论 收藏
分享
2 37 评论
分享
牛客网
牛客企业服务