8.12京东笔试ak攻略

T1

这题有点绕 其实可以直接枚举操作1的次数,然后计算经过操作1之后翻转后的字符串的操作2的次数 求最小值

int f(string &s){
    int l=0,r=s.size()-1,cnt=0;
    while(l<r){
        if(s[l]!=s[r]){
            cnt++;
        }
        l++;r--;
    }
    return cnt;
}
void solve(int u) {
    cin>>n>>s;
    int res=1e9;
    for(int i=0;i<n;i++){
        string t=s.substr(i)+s.substr(0,i);
        res=min(res,f(t)+i);
    }
    cout<<res<<endl;
}

T2

线性dp 定义f[i][j]为操作到第i个数的时候 以j结尾的方案数

初始化f[n][w[n]%10]=1

注意:如果本题n=1且w[1]>=10 则其他方案数均为0(这个样例比较狗,当时卡了很久,不写的话只能过96%)

状态转移方程

int a=(w[i]+j)%10,b=(w[i]*j)%10;

f[i][a]+=f[i+1][j]

f[i][b]+=f[i+1][j]

void solve(int u){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>w[i];
    }
    if(n==1){
        if(w[1]>=10){
            for(int i=0;i<10;i++)cout<<0<<" "; 
            return;
        }
    }
    f[n][w[n]%10]=1;
    for(int i=n-1;i>=1;i--){
        for(int j=0;j<10;j++){
            int a=(j+w[i])%10,b=(1ll*j*w[i])%10;
            f[i][a]=(f[i][a]+f[i+1][j])%mod;
            f[i][b]=(f[i][b]+f[i+1][j])%mod;
        }
    }
    for(int i=0;i<10;i++)cout<<f[1][i]<<" ";
}

T3

问题转换为给定n个点,求可以组成正方形的方案数(n<=2500)

可以使用n^2的方式暴力枚举

选两个点找两个方向是否有对应的点,(找的过程可以使用哈希表优化搜索)因为每个边都算了一次,所以答案除以4

unordered_map<int, vector<int>>mp;
bool check(int x, int y) {
    if (mp.count(x)) {
        for (auto& t : mp[x]) {
            if (t == y)return true;
        }
    }
    return false;
}
void solve(int u) {
    cin >> n >> m;
    vector<PII>v;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> g[i][j];
            if (g[i][j] == 'X') {
                v.push_back({i, j});
                mp[i].push_back(j);
            }
        }
    }
    n = v.size();
    ll res = 0;
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            int x1 = v[i].x, y1 = v[i].y, x2 = v[j].x, y2 = v[j].y;
            int x31 = x1 - (y1 - y2), y31 = y1 + (x1 - x2);
            int x41 = x2 - (y1 - y2),y41 = y2 + (x1 - x2);
            if (check(x31, y31) && check(x41, y41)) {
                res++;
            }
            int x32 = x1 + (y1 - y2), y32 = y1 - (x1 - x2);
            int x42 = x2 + (y1 - y2), y42 = y2 - (x1 - x2);
            if(check(x32,y32)&&check(x42,y42)){
                res++;
            }

        }
    }
    res /= 4;
    cout << res << endl;
}

#京东秋招##互联网大厂##后端开发##秋招##提前批#
互联网笔试真题题解 文章被收录于专栏

收录近两年互联网公司笔试真题解析,并提供Java,Python,C++三种语言版本的代码

全部评论
佬为啥这么厉害呀!!!😲😲😲上午刷到你美团也都ac了!
2
送花
回复
分享
发布于 2023-08-12 21:12 安徽
大佬,太强了
1
送花
回复
分享
发布于 2023-08-12 21:14 浙江
滴滴
校招火热招聘中
官网直投
y哥牛逼
1
送花
回复
分享
发布于 2023-08-13 00:07 北京
yhy 神!
点赞
送花
回复
分享
发布于 2023-08-12 21:02 北京
笔试全ak是吧
点赞
送花
回复
分享
发布于 2023-08-12 21:02 北京
请问为什么我考虑了元素为 1 的样例,通过率还是 96.88% 呢? ```java // ans: 1 0 0 0 3 3 0 0 0 1 private static void backtrack(long[] ans, int[] arr, int n, int idx) { if (n == 1) { // 只有一个元素 ans[arr[0]] = 1; return; } if (idx >= n - 2) { // 回溯结束 int a = arr[n - 2]; int b = arr[n - 1]; // 加法:arr[n - 1] + arr[n - 2] // 乘法:arr[n - 1] + arr[n - 2] ans[(a + b) % 10]++; ans[(a * b) % 10]++; return; } int cur = arr[idx]; // 当前数字 backtrack(ans, arr, n, idx + 1); long[] curAns = new long[10]; for (int i = 0; i < 10; i++) { curAns[(cur + i) % 10] += ans[i]; curAns[(cur * i) % 10] += ans[i]; } for (int i = 0; i < 10; i++) { ans[i] = (curAns[i]) % MOD; } } ```
点赞
送花
回复
分享
发布于 2023-08-12 21:06 上海
T2 "注意:如果本题n=1且w[1]>=10 则其他方案数均为0(这个样例比较狗,当时卡了很久,不写的话只能过96%)",怪不得我过不去
点赞
送花
回复
分享
发布于 2023-08-12 21:06 陕西
m
点赞
送花
回复
分享
发布于 2023-08-12 21:08 天津
我就是*** 第一题➕i我写成了➕1,怪不得一直没a
点赞
送花
回复
分享
发布于 2023-08-12 21:21 陕西
佬,能讲讲第二题嘛?没懂为什么第一种操作方法、第二种操作方法是用j和最后一个数操作,“int a=(j+w[i])%10,b=(1ll*j*w[i])%10;”这块
点赞
送花
回复
分享
发布于 2023-08-12 21:39 陕西
第二题我写法差不多,为啥只过了6%
点赞
送花
回复
分享
发布于 2023-08-12 22:35 上海
大佬思路太清晰了
点赞
送花
回复
分享
发布于 2023-08-12 22:43 湖北
y哥牛逼y哥牛逼
点赞
送花
回复
分享
发布于 2023-08-13 00:07 北京
第二题用暴力递归怎么做呢?我试了试这样有点问题
点赞
送花
回复
分享
发布于 2023-08-13 11:50 山东

相关推荐

28 93 评论
分享
牛客网
牛客企业服务