京东笔试C++ 题解

第一题:求1~N的最小公倍数。把每个数字分解质因数,算他们每个质因数的贡献,然后乘起来。我的代码没写好(算质因数不用这么慢的)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 100009
int fact[maxn];
bool prime[maxn];
ll mod = 987654321;
int cal(int t, int p) {
    int cnt = 0;
    while(t % p == 0) {
        cnt++;
        t /= p;
    }
    return cnt;
}
void first() {
    memset(prime, true, sizeof(prime));
    prime[1] = false;
    for(int i = 2; i <= 100000; i++) {
        int top = sqrt(i);
        for(int j = 2; j <= top; j++) {
            if(i % j == 0) {
                prime[i] = false;
                break;
            }
        }
    }
}
void solve(int Limit) {
    first();
    for (int i = 2; i <= Limit; i++) {
        int top = sqrt(i);
        for (int j = 2; j <= top; j++) {
            if(prime[j] && i % j == 0) {
                fact[j] = max(fact[j], cal(i, j));
            }
        }
        if(prime[i])
            fact[i] = max(fact[i], 1);
    }
}
int main() {
    ll n;
    cin>>n;
    solve(n);
    ll ans = 1;
    for(ll i = 1; i <= n; i++) {
        for(ll j = 1; j <= fact[i]; j++) {
            ans = ans * i % mod;
        }
    }
    cout<<ans<<endl;
    return 0;
}

第二题:去掉字符串构成回文。其实是经典的求回文子序列个数。但是我觉得题意是有坑的,题意描述的感觉不是这个意思。记忆化搜索dp。也可以直接dp。方程:
f[i][j] = dfs(i, j - 1) + dfs(i + 1, j) - dfs(i + 1, j - 1);
if(str[i] == str[j])
f[i][j] += dfs(i + 1, j - 1) + 1;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f[59][59];
string str;
ll dfs(int i, int j) {
    if(i > j) {
        return 0;
    }
    if(i == j) {
        f[i][j] = 1;
        return f[i][j];
    }
    if(f[i][j] != 0) {
        return f[i][j];
    }
    f[i][j] = dfs(i, j - 1) + dfs(i + 1, j) - dfs(i + 1, j - 1);
    if(str[i] == str[j])
        f[i][j] += dfs(i + 1, j - 1) + 1;
    return f[i][j];
}
int main() {
    cin>>str;
    int len = str.length();
    cout<<dfs(0, len - 1)<<endl;
    return 0;
}

第三题:象棋的马走K步之后到(X,Y)的方案数。直接递推。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[10][10][3];
ll mod = 1e9 + 7;
int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[8] = {-1, -2, -2, -1, 1, 2, 2, 1};
int check(int x, int y) {
    if(x >= 0 && x <= 8 && y >= 0 && y <= 8)
        return true;
    return false;
}
void cal(int x, int y, int state) {
    dp[x][y][state] = 0;
    for(int i = 0; i < 8; i++) {
        int tx = x + dx[i];
        int ty = y + dy[i];
        if(check(tx, ty)) {
            dp[x][y][state] = (dp[x][y][state] + dp[tx][ty][state ^ 1]) % mod;
        }
    }
}
int main() {
    int K;
    cin>> K;
    int state = 0, nowstate;
    dp[0][0][0] = 1;
    while(K--) {
        state = state ^ 1;
        for(int i = 0; i <= 8; i++) {
            for(int j = 0; j <= 8; j++) {
                cal(i, j, state);
            }
        }
    }
    int x, y;
    cin>>x>>y;
    cout<<dp[x][y][state]<<endl;
    return 0;
}
#春招##实习##笔试题目#
全部评论
啥?第三题不可以走出去?
点赞 回复 分享
发布于 2018-04-09 21:06
**,***题目不说清楚
点赞 回复 分享
发布于 2018-04-09 21:06
京东的象棋棋盘是9X9的棋盘。。。去他喵的
点赞 回复 分享
发布于 2018-04-09 21:08
太强了
点赞 回复 分享
发布于 2018-04-09 21:09
第三题,请教思路哪里出错了 #include <iostream> #include <vector> #include <limits.h> #include <algorithm> #include <math.h> #include <functional> #include <string>   using namespace std; typedef long long LL; const LL MOD = 1000000007; int X, Y; int K; int dx[] = { -2, -2, -1, -1, 1, 1, 2, 2 }; int dy[] = { 1, -1, 2, -2, 2, -2, 1, -1 }; void dfs(LL& res, int k, int i, int j){     if (k <= 0) {         if (i == X && j == Y)             res = (res + 1) % MOD;         return;     }     for (int t = 0; t < 8; ++t) {         int x = i + dx[t], y = j + dy[t];         if (0 <= x && x < 10 && 0 <= y && y < 10){             dfs(res, k - 1, x, y);         }     } } int main(){     while (scanf("%d", &K) != EOF) {         scanf("%d%d", &X, &Y);         LL res = 0;         dfs(res, K, 0, 0);         printf("%lld\n", res);     }     system("pause");     return 0; }
点赞 回复 分享
发布于 2018-04-09 21:09
第二题,其实是经典的求回文子序列个数。但是我觉得题意是有坑的,题意描述的感觉不是这个意思。
点赞 回复 分享
发布于 2018-04-09 21:10
象棋棋盘 8x8? 不是8x9的????
点赞 回复 分享
发布于 2018-04-09 21:12
9*9??? 我还特地数了,竟然都没数对。。。
点赞 回复 分享
发布于 2018-04-09 21:24
有没有人能详解一下第二题啊?没有看懂。。。
点赞 回复 分享
发布于 2018-04-09 21:34
假如输入是 ABCA 的时候,你这个算法输出是7, 但是按照题目的意思肯定不止7种: 回文: 移除顺序 A : ABC, ACB, BAC, BCA, CAB, CBA AA:  BC, CB B  :  ..... C :  ...... 还有,当 输入是 AAA的时候,算法输出是7, 但是题目的意思算应该只有3种: A: AA AA:A AAA:‘’ 是这样子么?
点赞 回复 分享
发布于 2018-04-10 00:29
大佬,你第二题的算法是求解回文数的数目,请问第二题你AC了么?
点赞 回复 分享
发布于 2018-04-10 00:33
//第二题---更好理解 int count_seq(string str, int low, int high) {  int result = 0;  if (high - low == 0) {   return 1;  }  if (high - low == 1) {   if (str[high] == str[low])    return 3;   else    return 2;  }  if (str[low] == str[high]) {   result = count_seq(str, low + 1, high) + count_seq(str, low, high - 1) + 1;  }  else {   result = count_seq(str, low + 1, high) + count_seq(str, low, high - 1) - count_seq(str, low + 1, high - 1);  }  return result; } int main() {  string str = "ABA";  cout << count_seq(str, 0, str.length() - 1) << endl; }
点赞 回复 分享
发布于 2018-04-11 15:58
第二题强,拆分加递归
点赞 回复 分享
发布于 2018-04-15 12:24

相关推荐

2024-12-10 17:38
广州新华学院 Node.js
想逆袭好楠:太紧凑了感觉,文字好多看的眼花,建议自我评价删了,因为自我评价都是吹嘘自己的,感觉没什么价值,然后改一下排版
点赞 评论 收藏
分享
评论
点赞
37
分享
牛客网
牛客企业服务