2017年校招全国统一模拟笔试(第二场)编程题参考代码汇总

第二场编程题合集:https://www.nowcoder.com/test/4546329/summary


最长公共子串

分析

注意跟最长公共子序列的区别,还有空格也作为字符在匹配就好了,经典题。

参考code

#include <bits/stdc++.h>

using namespace std;

char s1[55], s2[55];
int main() {  
    gets(s1);
    gets(s2);
    int ans = 0, k;
    for(int i = 0; i < strlen(s1); ++i) { 
        for(int j = 0; j < strlen(s2); ++j) {  
            for(k = 0; s1[i + k] && s2[j + k] && s1[i + k] == s2[j + k]; k++);
            if(k > ans) ans = k; 
        }  
    }
    cout << ans << endl;
    return 0;  
}

找整除

分析

裸暴力不能通过所有数据。所以调整a到一个可以被c整除的位置,然后以c为步长计算就好了。。

参考code

#include <bits/stdc++.h>

using namespace std;

int main() {
    int a, b, c;
    cin >> a >> b >> c;
    while(a % c != 0) a++;
    if(a > b)    
        cout << 0 << endl;
    else
        cout << (b - a) / c + 1 << endl;
    return 0;
}

组装三角形

分析

暴力枚举三边,然后check一下就好了。

参考code

#include <bits/stdc++.h>

using namespace std;

int v[55];
int check(int a, int b, int c) {
    return a < b + c && b < a + c && c < a + b;
}
int main() {
    int n, ans = 0;
    cin >> n;
    for(int i = 0; i < n; i++) cin >> v[i];
    for(int i = 0; i < n; i++) {
        for(int j = i + 1; j < n; j++) {
            for(int k = j + 1; k < n; k++) {
                if(check(v[i], v[j], v[k])) ans++;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

最小矩阵

分析

维护X,Y坐标最大最小坐标,然后计算一发就好了。

参考code

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;
    int minx = 10000, maxx = -100000, miny = 100000, maxy = -100000;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        minx = min(minx,x);
        maxx = max(maxx,x);
        miny = min(miny,y);
        maxy = max(maxy,y);
    }
    cout << (maxx - minx) * (maxy - miny) << endl;
    return 0;
}

平衡数

分析

枚举断点暴力check一下就好。

参考code

#include <bits/stdc++.h>

using namespace std;

string solve(int number) {
    ostringstream oss;
    oss << number;
    string s = oss.str();
    int n = s.length();
    long long n1, n2;
    for(int i = 1; i < n; i++) {
        n1 = n2 = 1;
        for(int j = 0; j < i; j++)
            n1 *= s[j] - '0';
        for(int j = i; j < n; j++)
            n2 *= s[j] - '0';
        if(n1 == n2)
            return "YES";
    }
    return "NO";
}
int main() {
    int x;
    cin >> x;
    cout << solve(x) << endl;
    return 0;
}

字符串分类

分析

我们可以容易的观察到,两个字符串是同一类当且仅当构成他们的字符集合相同且个数也相同。于是对于每个字符串进行排序,最后再对整个字符串数组排序一下,扫一遍计算个数就好。

参考code

#include <bits/stdc++.h>

using namespace std;

vector<string> v;
int main() {
    int n;
    cin >> n;
    for(int i = 0; i < n; i++) {
        string x;
        cin >> x;
        sort(x.begin(), x.end());
        v.push_back(x);
    }
    sort(v.begin(), v.end());
    int ans = 0;
    string tmp("");
    for(int i = 0; i < v.size(); i++) {
        if(tmp != v[i]) tmp = v[i], ans++;
    }
    cout << ans << endl;
}

创造新世界

分析

这道题很容易想到使用贪心。。然而。。 一种比较容易想到的贪心是尽量去满足更短的字符串。但是我们考虑2个0和5个1,要组成的字符串是{00, 011, 0111}.这样贪心的答案是1,其实我们可以组成2个。 另外一种贪心是尽量使用更多的1或者0.考虑我们当前有5个0和4个1,组成的字符串是{100000, 110, 110},这样又是不行的。。 这道题的正解是动态规划,首先预处理出需要组成的每个字符串需要0和1的个数,然后dp[i][j]表示使用i个0和j个1能组成的个数,然后对于枚举每个字符串做个转移就行。。详情看代码。 时间复杂度 O(MAX_STRINGS MAX_ZEROES MAX_ONES)

参考code

#include <bits/stdc++.h>

using namespace std;

const int maxn = 500;

vector <string> *l;

int m, n, x;
int solve(int i, int numZeroes, int numOnes) {
    vector<string> &list = *l;
    if(i == list.size()-1) {
        for(int x = 0; x < list[i].size(); ++x) {
            if(list[i][x] == '1') --numOnes;
            if(list[i][x] == '0') --numZeroes;
        }
        if((numOnes | numZeroes) >= 0) return 1; 
        else return 0;
    }
    int a = solve(i+1, numZeroes, numOnes);
    for(int x = 0; x < list[i].size(); ++x) {
            if(list[i][x] == '1') --numOnes;
            if(list[i][x] == '0') --numZeroes;
    }
    if((numOnes | numZeroes) < 0) return a;
    int b = 1 + solve(i+1, numZeroes, numOnes);
    return max(a, b);
}
int main() {
    vector<string> v;
    cin >> x >> n >> m;
    for(int i = 0; i < x; i++) {
        string tmp; cin >> tmp;
        v.push_back(tmp);
    }
    l = &v;
    cout << solve(0, n, m) << endl;
    return 0;
}

优美的回文串

分析

对于一个字符串,我们依次替换掉字符是不影响最后结果的统计的。。 比如AJNFHALJJFJ,我们可以依次替换为a, b, c, d, e 和 f变为abcdeafbbdb,于是我们现在就挨着去生成长度为n的这样的字符串,然后暴力统计出满足条件的个数。最后计算上每个的贡献就行了。。 考虑abcdeafbbdb,第一个a可以换为26个字符的任意一个,b可以换为25个中的一个...... 所以对于一个有k种字符的字符串贡献就是26 × 25 × ... × (26-k+1)。计算出答案即可

参考code

#include <iostream>
#include <algorithm>

using namespace std;

long long cnt[12];
long long res = 0;
int M, K, N;
char s[12];
void solve(int k, int p) {
    if(k == 0) {
        int tmp = 0;
        for(int i = 0; i < N - M + 1; i++) {
            bool ok = true;
            for(int j = 0; j < M / 2; j++) {
                if(s[i + j] != s[i + M - 1 - j]) {
                    ok = false;
                    break;
                }
            }
            if(ok) tmp++;
        }
        if(tmp >= K) {
            res += cnt[p];
        }
        return ;
    }
    for(int i = 0; i < p + 1; i++) {
        s[k - 1] = 'a' + i;
        solve(k - 1, max(p, i + 1));
    }
}
int main() {
    cin >> N >> M >> K;
    cnt[0] = 0; cnt[1] = 26;
    for(int i = 2; i <= N; i++) {
        cnt[i] = cnt[i - 1] * (26 - i + 1);
    }
    solve(N, 0);
    cout << res << endl;
}
#C++工程师##iOS工程师#
全部评论
平衡数:对所有位的乘积判断是否是一个平方数。 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { getValue(in.nextInt()); } } public static void getValue(int data) { String s = String.valueOf(data); int R = 1; for (int i = 0; i < s.length(); i++) { R = R * (s.charAt(i) - '0'); } int r = (int) Math.sqrt((double) R); if (r * r == R) System.out.println("YES"); else System.out.println("NO"); } }
点赞 回复 分享
发布于 2017-03-23 21:25
膜果姐!
点赞 回复 分享
发布于 2017-03-23 21:08
字符串扔set就好了
点赞 回复 分享
发布于 2017-03-23 21:11
优美回文传没看懂啊。牛姐姐
点赞 回复 分享
发布于 2017-03-23 21:14
好歹题目也放上来。。
点赞 回复 分享
发布于 2017-03-23 21:16
优美的回文串这题解法没看懂。。。
点赞 回复 分享
发布于 2017-03-23 21:19
平衡数那道题不用那么暴力,对于一个字符串只有1个0的,一定是不行的,如果有1个以上的0,一定是可以的,如果不包括0,可以先把字符串从中间分割,看左半部分和右半部分是否相等,如果相等直接返回,不相等如果左边大,就左边除以,右边乘以,否则相反,一直到最前或最后,或者出现相反情况,比如本来左边大于右边,后来右边大于左边了,直接结束就可以了.
点赞 回复 分享
发布于 2017-03-23 22:00
惊了!!!
点赞 回复 分享
发布于 2017-03-23 21:12
6666
点赞 回复 分享
发布于 2017-03-23 21:12
正处那道题,直接除了取整,然后相减就好了
点赞 回复 分享
发布于 2017-03-23 21:12
认真学习
点赞 回复 分享
发布于 2017-03-23 21:12
牛家——果神。。。。果然,威武!
点赞 回复 分享
发布于 2017-03-23 21:15
6666,膜拜。
点赞 回复 分享
发布于 2017-03-23 21:16
为啥在大佬的眼里题目都这么简单
点赞 回复 分享
发布于 2017-03-23 21:16
居然是暴力统计回文数........
点赞 回复 分享
发布于 2017-03-23 21:17
JAVA后台第一题 import java.util.Scanner; public class NiuKe { public static void main(String[] args) { Scanner in=new Scanner(System.in); String n=in.nextLine(); for(int i=0;i<n.length()-1;i++){ int a=1,b=1; for(int j=0;j<=i;j++){ a=a*Integer.parseInt(String.valueOf(n.charAt(j))); } for(int k=i+1;k<n.length();k++){ b=b*Integer.parseInt(String.valueOf(n.charAt(k))); } if(a==b){ System.out.println("YES"); return; } } System.out.println("NO"); } }
点赞 回复 分享
发布于 2017-03-23 21:17
JAVA后台第二题 import java.lang.reflect.Array; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class NiuKe2 { public static void main(String[] args) { Scanner in=new Scanner(System.in); Map<String, Integer> map=new HashMap<>(); int n=in.nextInt(); String[] tem=new String[n]; int count=0; for(int i=0;i<n;i++){ tem[i]=in.next(); char[] a=tem[i].toCharArray(); Arrays.sort(a); if(!map.containsKey(String.copyValueOf(a))){ map.put(String.copyValueOf(a), 1); count++; } } System.out.println(count); } }
点赞 回复 分享
发布于 2017-03-23 21:18
字符串分类哪个,竟然能直接使用自带api?**,我还吭吭哧哧嵌套好几层循环比较。 先排序,然后扔进set返回大小不就直接完了吗! 这样使用自带api?那样不是很简单了吗? 首先,想了一下有没有巧妙的思路,想半天,没想出来,然后就一个一个字符比较大小,花费了很长时间,第三题没做。竟然可以用自带api!
点赞 回复 分享
发布于 2017-03-23 21:20
渣渣一个编程题都没搞定,耻辱一下自己!
点赞 回复 分享
发布于 2017-03-23 21:27
创造新世界,本来还想想一个好的姿势,一偷懒,看到是20,就dfs了,没想到标程也是
点赞 回复 分享
发布于 2017-03-23 21:27

相关推荐

10-11 17:45
门头沟学院 Java
走吗:别怕 我以前也是这么认为 虽然一面就挂 但是颇有收获!
点赞 评论 收藏
分享
点赞 55 评论
分享
牛客网
牛客企业服务