10.18 携程笔试编程题1、2、4题解


1. 给你一个整数x和k,让你反转x的前k位。
a, k = input().split()
k = int(k)
print(int(a[k-1::-1]+a[k:]))

2. 给你一个长度小于等于10的字符串,求合法字符串的个数。
合法字符串:串中所有相邻两个字符都不相同
#include <bits/stdc++.h>
using namespace std;
int main() {
    string s; cin >> s;
    const int n = s.length();
    sort(s.begin(), s.end());
    int cnt = 0;
    do {
        bool ok = true;
        for (int i = 1; i < n; i++) {
            if (s[i] == s[i-1]) {
                ok = false;
                break;
            }
        }
        cnt += ok;
    } while (next_permutation(s.begin(), s.end()));
    cout << cnt << endl;
    return 0;
}

3. 题目大致意思是给定4个数,a,b,low,high。
每次操作你可以给a加上x,其中low<=x<=high。
求最终使a=b的最小和最大操作数。
无解输出-1.
条件:0 <= a <= b <= 1e9
1 <= low <= high <= 1e9
这题不会。有会的大佬麻烦给个思路,谢谢。


4. 给你一个数组和一个数x,从数组中任取两个数,求满足这两个数的乘积末尾至少有x个0的方案数。

思路:
对于两个数a和b,如果它们的因子10、2、5的个数分别为x1, x2, x3,y1,y2,y3,那么它们的乘积末尾总共有x1+y1+min(x2, y3)+min(x3, y2)。可以记录下数组中含有不同10、2、5因子个数各有多少个,剩下的就是组合问题了。
假如有x个a和y个b,而a*b一共能产生target个0。如果a和b相等,则x和y也相等,这种情况就相当于x个相同数中取2个,一共有Cn2=n*(n-1)/2种方案;如果a和b不相等,则一共有x*y/2种方案。
因为2**31>1e9,5**14>1e9,所以最大计算量应该为(31*14*10)**2,大概在8个数量级的样子。数组大小1e5,双重循环暴力判断运算量就是10个数量级了。
补充:
再想了一下,这里可以只考虑因子2和5,可以再减两个数量级,这里就不实现了。

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, x;
    cin >> n >> x;
    vector<int> v(n);
    for (int i = 0; i < n; i++) {
        cin >> v[i];
    }
    int cnt[11][32][15]{0};
    for (int i = 0; i < n; i++) {
        int val = v[i];
        int f_10 = 0, f_2 = 0, f_5 = 0;
        while (val%10 == 0) {
            val /= 10;
            f_10 ++;
        }
        while (val%2 == 0) {
            val /= 2;
            f_2 ++;
        }
        while (val%5 == 0) {
            val /= 5;
            f_5 ++;
        }
        cnt[f_10][f_2][f_5] ++;
    }
    long long nums[19]{0};
    for (int i = 0; i < 11; i++) {
        for (int j = 0; j < 32; j++) {
            for (int k = 0; k < 15; k++) {
                for (int ii = 0; ii < 11; ii++) {
                    for (int jj = 0; jj < 32; jj++) {
                        for (int kk = 0; kk < 15; kk++) {
                            int cnt_0 = i+ii+min(j, kk)+min(jj, k);
                            nums[cnt_0] += i==ii&&j==jj&&k==kk ? 1LL*cnt[i][j][k]*(cnt[i][j][k]-1) : 1LL*cnt[i][j][k]*cnt[ii][jj][kk];
                        }
                    }
                }
            }
        }
    }

    long long ans = 0;
    for (int i = x; i < 19; i++) {
        ans += nums[i]/2;
    }
    cout << ans << endl;
    return 0;
}


#携程笔试#
全部评论
4题好思路
点赞 回复 分享
发布于 2022-10-19 00:39 湖北
C++  YYDS
点赞 回复 分享
发布于 2022-10-19 09:55 北京
第三题感觉自己思路没啥问题?但是一直超时...
点赞 回复 分享
发布于 2022-10-19 10:03 北京
考虑2和5 一直超时
点赞 回复 分享
发布于 2022-10-19 15:10 浙江

相关推荐

喜欢吃蛋糕仰泳鲈鱼是我的神:字节可以找个hr 给你挂了,再放池子捞
点赞 评论 收藏
分享
2 7 评论
分享
牛客网
牛客企业服务