京东2019春招编程题参考代码

数内排序

分析

字符串读入,逆序排序即可。

时间复杂度

O(len(x)*log(len(x)))

参考代码

#include <bits/stdc++.h>

using namespace std;

int main() {
    string x;
    cin >> x;
    sort(x.begin(), x.end());
    reverse(x.begin(), x.end());
    cout << x << endl;
    return 0;
}

幸运时刻

分析

按题意模拟即可。

时间复杂度

O(n)

参考代码

#include <bits/stdc++.h>

using namespace std;

int n;
int main() {
    cin >> n;
    string s;
    int cnt = 0;
    int flag;
    for(int i = 0; i < n; i++) {
        cin >> s;
        flag = 0;
        if(s[0] == s[3] && s[1] == s[4]) flag = 1;
        if(s[0] == s[1] && s[3] == s[4]) flag = 1;
        if(s[0] == s[4] && s[1] == s[3]) flag = 1;
        if(flag) cnt++;
    }
    cout << cnt << endl;
}

有趣的硬币

分析

根据有趣硬币的定义,挨着判断统计即可。

时间复杂度

O(n)

参考代码

#include <bits/stdc++.h>

using namespace std;

string s;
int main() {
    cin >> s;
    s = s[0] + s;
    s = s + s[s.size() - 1];
    int cnt = 0;
    for(int i = 1; i < s.size() - 1; i++) {
        if(s[i] != s[i - 1] || s[i] != s[i + 1]) {
            cnt++;
        }
    }
    cout << cnt << endl;
    return 0;
}

整除

分析

本质是找1~n的最小公倍数,
根据唯一分解定理和最小公倍数的定义。。。
求每个素因子的最大个数相乘即可。

时间复杂度

O(n*sqrt(n))

参考代码

#include <bits/stdc++.h>

using namespace std;

const int maxn = 100000 + 5;
int tmp[maxn];
int n;
int main() {
    cin >> n;
    for(int i = 1; i <= n; i++) {
        int k = i;
        for(int j = 2; j * j <= n; j++) {
            int s = 0;
            while(k % j == 0) {
                s++;
                k /= j;
            }
            tmp[j] = max(tmp[j], s);
        }
        if(k > 1) tmp[k] = max(tmp[k], 1);
    }
    long long res = 1;
    for(int i = 1; i <= 100000; i++) {
        for(int j = 0; j < tmp[i]; j++) {
            res = res * i % 987654321;
        }
    }
    cout << res << endl;
    return 0;
}

牛牛下象棋

分析

dp[i][a][b]表示i次移动后,马位于坐标(a,b)的情况数。
考虑下一步的八种移动方式对应的8个坐标分别为(a1,b1)...(a8,b8),则状态转移方程如下:
dp[i+1][a1][b1] += dp[i][a][b]
dp[i+1][a2][b2] += dp[i][a][b]
...
dp[i+1][a8][b8] += dp[i][a][b]
初始状态为除了dp[0][0][0] = 1,其余都为0。答案就是dp[K][X][Y]。

时间复杂度

O(81*K)

参考代码

#include <bits/stdc++.h>

using namespace std;

long long dp[100005][10][10];
int d[10][2] = {{1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {2, 1}, {2, -1}, {-2, 1}, {-2, -1}};
int main() {
    int k, X, Y, tx, ty;
    scanf("%d%d%d", &k, &X, &Y);
    dp[0][0][0] = 1;
    for(int i = 0; i < k; i++) {
        for(int x = 0; x <= 8; x++) {
            for(int y = 0; y <= 8; y++) {
                for(int j = 0; j < 8; j++) {
                    tx = x + d[j][0];
                    ty = y + d[j][1];
                    if(0 <= tx && tx <= 8 && 0 <= ty && ty <= 8)
                        dp[i+1][tx][ty] = (dp[i + 1][tx][ty] + dp[i][x][y]) % 1000000007;
                }
            }
        }
    }
    printf("%lld\n", dp[k][X][Y]);
    return 0;
}

牛牛的括号匹配

分析

考虑如何判断一个串是否合法的过程:
依次处理字符,若是'('则入栈,若是')'则从栈中弹出一个'('. 若没有'('则不合法.
那么此题就是上述过程的变种,在处理过程中允许两次变换.可以只考虑')'->'('的方向.
1、如果当前是'(',直接入栈.
2、如果当前是')',如果栈非空,则弹出一个'('; 如果栈空就把当前的')'变成'('入栈. (标记最多只能变化一次).
用flag标记是否有将')'变为'('的操作. 结果栈要么为空,要么全是'('.

  1. 如果整个字串没有被处理完,那么肯定是"No".
  2. 如果flag=0, 那么要求没有'('剩下.
  3. 如果flag=1, 那么结果栈中的'('只能是两个. "((" -> "()".

时间复杂度

O(len(s))

参考代码

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 10;

char str[maxn];
stack<char> s;

int main() {
    int t;
    cin >> t;
    while(t--) {
        while(!s.empty()) s.pop();
        scanf("%s", str);
        int n = strlen(str);
        if(n == 2) {
            if(str[0] == '(' && str[1] == ')') {
                puts("No");
                continue;
            }
        }
        int i;
        int flag1 = 0;
        for(i = 0; i < n; i++) {
            if(str[i] == '(') {
                s.push('(');
            } else {
                if(!s.empty()) s.pop();
                else {
                    if(flag1) break;
                    flag1 = 1;
                    s.push('(');
                }
            }
        }
        if(i == n) {
            if(!flag1) {
                if(s.empty()) puts("Yes");
                else puts("No");
            }
            else {
                if(s.size() != 2) puts("No");
                else puts("Yes");
            }
        }
        else puts("No");
    }
    return 0;
}

分解整数

分析

范围巨大。。
但是直觉上觉得可以很快出答案,
于是答案枚举一个数,判断另外一个数的合法性。
就跑过了。。

时间复杂度

O(跑得过)

参考代码

#include <bits/stdc++.h>

int main() {
    int t;
    long long n, x, y;
    scanf("%d", &t);
    while(t--) {
        scanf("%lld", &n);
        if(n & 1)
            printf("No\n");
        else {
            for(y = 2; y <= n; y += 2) {
                if(n % y == 0 && ((n / y) & 1)) {
                    x = n / y;
                    break;
                }
            }
            printf("%lld %lld\n", x, y);
        }
    }
    return 0;
}

生成回文串

分析

dp[l][r]表示区间 [l, r] 内的回文串数目。
于是dp[l][r] = dp[l][r - 1] + dp[l + 1][r],
根据s[l] ?= s[r], 来看是+1还是减掉重复的部分。

时间复杂度

O(n^2)

参考代码

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int maxn = 50 + 5;
LL dp[maxn][maxn];
char s[maxn];
int main() {
    scanf("%s", s + 1);
    int len = strlen(s + 1);
    memset (dp, 0, sizeof(dp));
    for(int i = 1; i <= len; i++) {
        for(int l = 1; l + i - 1 <= len; l++) {
            int r = l + i - 1;
            dp[l][r] += dp[l + 1][r];
            dp[l][r] += dp[l][r - 1];
            if (s[l] == s[r]) dp[l][r] += 1;
            else dp[l][r] -= dp[l + 1][r - 1];
        }
    }
    printf ("%lld\n", dp[1][len]);
    return 0;
}
#春招#
全部评论
牛牛的下象棋复杂度应该是O(9*9*8*K), 不是 O(81K) 同样的算法,Python版本只能过60% 后面超时。
点赞 回复 分享
发布于 2018-04-09 21:47
前排给大佬招妹子,传媒大二的优先
点赞 回复 分享
发布于 2018-04-09 21:12
刘明
点赞 回复 分享
发布于 2018-04-09 21:13
膜拜
点赞 回复 分享
发布于 2018-04-09 21:16
666
点赞 回复 分享
发布于 2018-04-09 21:17
给大佬递茶
点赞 回复 分享
发布于 2018-04-09 21:25
牛牛下象棋的那个y应该是判定是否<10,而不是小于8
点赞 回复 分享
发布于 2018-04-09 21:26
棋盘那个每次相加都要mod,唉!还是刷题少
点赞 回复 分享
发布于 2018-04-09 21:26
大神
点赞 回复 分享
发布于 2018-04-09 21:30
分解整数,可以让偶数从2开始,一直乘以2,原来的数一直除以2,直到原来的数为奇数时结束,则奇数、偶数则为所求,复杂度应该是 log(n)?
点赞 回复 分享
发布于 2018-04-09 21:36
大佬,为什么回文串一样的只过了70,因为你用了constintmaxn =50+5吗?
点赞 回复 分享
发布于 2018-04-09 21:38
请问一下  牛牛的括号匹配 这道题我只通过90%,我的想法是用一个变量i来记录当前遇到括号的情况,遇到'('则i++,遇到')'i--,每次都判断一下,当i < -2时,失败,因为出现三个以上的')'括号是无法交换成功的。最后遍历完之后,如果i==0则成功,不为0则失败。     思路根源在于因为最后i会等于0,说明左右括号数量一样,那么最差会有'..)..)..(..(..'的情况(这里的'..'表示的是可能出现0个或多个括号),且出现第二个')'时i == -2,这时可以将最右边的'('和其交换,形成'..(..)..(..)..'的情况。     请问这样的思路有什么问题吗?
点赞 回复 分享
发布于 2018-04-09 21:41
console.log("大佬6666666");
点赞 回复 分享
发布于 2018-04-09 21:45
分解整数我这样写超时了,用的Java,换个思路就过了,但是感觉时间复杂度是一样的,好气啊
点赞 回复 分享
发布于 2018-04-09 21:54
我这一题写了好多测试都过了,但是提交就过10%,感觉自己陷入了思路死角,求各位大佬指点 import java.util.Scanner; import java.util.Stack; /** * @Author: * @Date: Created in 18:51 2018/4/9 */ public class Test03 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); sc.nextLine(); for (int j = 0; j < n; j++) { String str = sc.nextLine(); Stack<Character> stack = new Stack<>(); stack.push(str.charAt(0)); for (int i = 1; i < str.length(); i++) { if (str.charAt(i) == '(') { stack.push(str.charAt(i)); } else if (str.charAt(i)==')'){ if (!stack.isEmpty()) { if (stack.peek().equals('(')) stack.pop(); else stack.push(str.charAt(i)); } else stack.push(str.charAt(i)); } } if (stack.size() == 2) { char c = stack.pop(); if (c=='(' && stack.pop().equals(')')) System.out.println("Yes"); else System.out.println("No"); } else System.out.println("No"); } } }
点赞 回复 分享
发布于 2018-04-09 21:56
第一题给的那两个个例子我都不知道咋得出来的,为什么xxy可以得到5个,aba能得到3个,大佬能解释一下吗?
点赞 回复 分享
发布于 2018-04-09 22:16
import sys n = int(sys.stdin.readline().strip()) ans = 0 nums = [] for i in range(n): line = sys.stdin.readline().strip() nums.append(int(line)) res =[] for n in nums: if (n%2 == 1): print("No") else: a = n / 2 while(a % 2 == 0 ): a = a / 2 b = n / a c = n / b print c, b
点赞 回复 分享
发布于 2018-04-09 22:22
就是大佬你是不是那种金牌拿到手软的那种
点赞 回复 分享
发布于 2018-04-09 22:24
牛逼
点赞 回复 分享
发布于 2018-04-09 22:58
从哪可以找到原题啊
点赞 回复 分享
发布于 2018-04-11 19:11

相关推荐

10-25 12:05
已编辑
湖南科技大学 Java
若梦难了:我有你这简历,已经大厂乱杀了
点赞 评论 收藏
分享
点赞 123 评论
分享
牛客网
牛客企业服务