8.23腾讯后台笔试解法分享(全AC,C++)

1. 除了第K个数全部打出来即可
int n;
int k;
void solve() {
    cin>>n>>k;
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        if(i!=k-1) cout<<x<<" ";
    }
    cout<<endl;
}
2. 把所有长度小于等于K的子串排序找第K个即可。这样保证前K个字串一定被选择同时不会超时。
string s;
int k;
int n;
void solve() {
    cin>>s>>k;
    set<string> ss;
    n = s.size();
    for(int i=0;i<n;i++){
        for(int j=1;j<=k&&i+j<=n;j++){
            ss.insert(s.substr(i,j));
        }
    } 
    for(int i=1;i<k;i++){
        ss.erase(ss.begin());
    }
    cout<<*ss.begin()<<endl;
}
3. 找到小于N的最大的99……9然后拆分即可(我模板用宏#define int long long,没贴进来)
int n;

void solve() {
    cin>>n;
    int x = n;
    int d = 0;
    int ans = 0;
    while(x>=10){
        d *= 10;
        d += 9;
        x /= 10;
        ans += 9;
    }
    int y = n-d;
    while(y){
        ans += y % 10;
        y /= 10;
    }
    cout<<ans<<endl;
    
}
4. Top-down dp,dp[l][r]代表解决l到r区间的最小次数。按区间长度遍历,dp[l][r]初始化成(r-l+1),因为可以对每个木板竖着刷一次。如果横着刷,我们刷arr[l]...arr[r]中最小的次,然后分割成小区间,求和。然后取两者最小值。
int n;
int arr[5001];

int dfs(int l, int r){
    if(l==r){
        if(arr[l]==0) return 0;
        else return 1;
    }

    int ans = r-l+1;
    int minl = INT_MAX;
    for(int i=l;i<=r;i++){
        minl = min(minl, arr[i]);
    }
    int ans1 = minl;
    int curl = -1;
    for(int i=l;i<=r;i++){
        arr[i] -= minl;
        if(arr[i] > 0){
            if(i==0 || arr[i-1]==0){
                curl = i;
            }
            if(i==r){
                ans1 += dfs(curl, i);
            }
        }else{
            if(i>0 && arr[i-1] > 0){
                ans1 += dfs(curl, i-1);
            }
        }
    }
    return min(ans, ans1);
}

void solve() {
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>arr[i];
    }
    cout<<dfs(0,n-1)<<endl;
}
5. 二维DP。dp[i][j]代表区间i到j的答案。首先检查i到j是否是回文,如果是的话答案是1,如果不是的话遍历所有分割区间方法求和取最小值。
int n;
string s;
int dp[401][401];
int q;
bool check(int i, int j){
    for(int k=0;k<(j-i+1)/2;k++){
        if(s[i+k] != s[j-k]) return false;
    }
    return true;
}
void solve() {
    cin>>s;
    n = s.size();
    memset(dp,0x3f,sizeof(dp));
    for(int l=0;l<n;l++){
        for(int i=0;i+l<n;i++){
            int j = i+l;
            if(check(i,j)) dp[i][j] = 1;
            else{
                for(int k=i+1;k<=j;k++){
                    dp[i][j] = min(dp[i][j], dp[i][k-1]+dp[k][j]);
                }
            }
        }
    }
    cin>>q;
    for(int i=0;i<q;i++){
        int a,b;
        cin>>a>>b;
        cout<<dp[a-1][b-1]<<endl;
    }
}




#笔经##腾讯##C++工程师#
全部评论
tql,巨佬,我一看你的学校就知道你为什么这么强了
3 回复 分享
发布于 2020-08-23 22:26
tql
点赞 回复 分享
发布于 2020-08-23 22:18
第一题java卡io,哭了😒
点赞 回复 分享
发布于 2020-08-23 22:22
tql,膜拜巨佬
点赞 回复 分享
发布于 2020-08-23 22:24
第一题不超时?我java一样,直接超时,第三题90%
点赞 回复 分享
发布于 2020-08-23 22:33
第一题我就这样,只过了75,有毒吧。。。
点赞 回复 分享
发布于 2020-08-23 23:07
谢谢巨佬~
点赞 回复 分享
发布于 2020-08-23 23:14
太强了,我笔试太紧张了,有思路但是没全ac,好难啊
点赞 回复 分享
发布于 2020-08-23 23:23
大佬,能请教下第4题吗?横着刷的时候,分割小区间再求和,能解释一下吗?谢谢~
点赞 回复 分享
发布于 2020-08-23 23:27
点赞 回复 分享
发布于 2020-08-23 23:30
第二题这么写不会MLE吗,按理说只要维护一个大小为k的set就行了
点赞 回复 分享
发布于 2020-08-24 08:29
谢谢楼主分享,tql
点赞 回复 分享
发布于 2020-08-24 16:05
点赞 回复 分享
发布于 2020-09-06 14:46

相关推荐

白菜小丑呜呜:Radis写错了兄弟
点赞 评论 收藏
分享
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
12-26 09:30
点赞 评论 收藏
分享
评论
17
85
分享
牛客网
牛客企业服务