牛客网2017年校招全国统一模拟笔试(第一场)编程题集合

原题链接https://www.nowcoder.com/test/4236887/summary
1.牛牛有一个鱼缸。鱼缸里面已经有n条鱼,每条鱼的大小为fishSize[i] (1 ≤ i ≤ n,均为正整数),牛牛现在想把新捕捉的鱼放入鱼缸。鱼缸内存在着大鱼吃小鱼的定律。经过观察,牛牛发现一条鱼A的大小为另外一条鱼B大小的2倍到10倍(包括2倍大小和10倍大小),鱼A会吃掉鱼B。考虑到这个,牛牛要放入的鱼就需要保证:
(1)放进去的鱼是安全的,不会被其他鱼吃掉
(2)这条鱼放进去也不能吃掉其他鱼
鱼缸里面已经存在的鱼已经相处了很久,不考虑他们互相捕食。现在知道新放入鱼的大小范围minSize,maxSize,牛牛想知道有多少种大小的鱼可以放入这个鱼缸。
题目有点水,不需要考虑新放入的鱼之间会互相吃掉

#include using namespace std; int a[55]; int mi,ma; int n; int main(){ cin >> mi >> ma; cin >> n; for(int i = 0; i < n; i++) cin >> a[i]; int ans = 0; for(int i = mi; i <= ma; i++){ int flag = 1; for(int j = 0; j < n; j++){ if( (i >= a[j] * 2 && i <= a[j] * 10) || (i * 2 <= a[j] && i * 10 >= a[j]) ){ flag = 0; } } if(flag) ans++; } cout << ans << endl; }

2.如果一个单词通过循环右移获得的单词,我们称这些单词都为一种循环单词。 例如:picture 和 turepic 就是属于同一种循环单词。 现在给出n个单词,需要统计这个n个单词中有多少种循环单词。
数据量比较小,就使用了STL的Map来实现,将每个字符串的所有循环形式存起来,每次有新的字符串时先判断是否已经存在,如果已经存在则统计结果+1,否则将其所有循环形式进行存储
#include #include #include using namespace std; int n; map mp; int main() { while (scanf("%d", &n) != EOF) { string s, tem; int ans = 0,key=0; for (int i = 0; i < n; i++) { cin >> s; if (mp[s] == 0) ans++; key = 0; for (int j = 0; j < s.length(); j++) { tem = s.substr(j, s.length() - j)+ s.substr(0, j); mp[tem] = 1; } } cout << ans << endl; } return 0; }

3.DNA分子是以4种脱氧核苷酸为单位连接而成的长链,这4种脱氧核苷酸分别含有A,T,C,G四种碱基。碱基互补配对原则:A和T是配对的,C和G是配对的。如果两条碱基链长度是相同的并且每个位置的碱基是配对的,那么他们就可以配对合成为DNA的双螺旋结构。现在给出两条碱基链,允许在其中一条上做替换操作:把序列上的某个位置的碱基更换为另外一种碱基。问最少需要多少次让两条碱基链配对成功
水题,直接统计下标相同的位置上匹配的内容,如果匹配则+1,最后用总长度-匹配长度即可
#include #include using namespace std; int main() { int count = 0; string str1; string str2; while (cin >> str1 >> str2) { for (int i = 0; iif (str1[i] == 'A'&&str2[i] == 'T') count++; if (str1[i] == 'G'&&str2[i] == 'C') count++; if (str1[i] == 'C'&&str2[i] == 'G') count++; if (str1[i] == 'T'&&str2[i] == 'A') count++; } } cout << str1.size() - count << endl; return 0; }

4.牛牛的好朋友羊羊在纸上写了n+1个整数,羊羊接着抹除掉了一个整数,给牛牛猜他抹除掉的数字是什么。牛牛知道羊羊写的整数神排序之后是一串连续的正整数,牛牛现在要猜出所有可能是抹除掉的整数。例如:
10 7 12 8 11 那么抹除掉的整数只可能是9
5 6 7 8 那么抹除掉的整数可能是4也可能是9
#include #include #include #include using namespace std; int n; int a[102]; int main() { while (scanf("%d", &n) != EOF) { for (int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a + n); int ans = -1,key=0; for (int i = 0; i < n - 1; i++) { if (a[i] + 1 == a[i + 1]) continue; else if (a[i] + 2 == a[i + 1]) { ans = a[i] + 1; key++; } else if (a[i + 1] - a[i] > 2) { ans = -2; break; } } if (ans == -1 && key == 0) { if (a[0] - 1 < 1) cout << a[n - 1] + 1 << endl; else cout << a[0] - 1 << " " << a[n - 1] + 1 << endl; } else if (key == 1) cout << ans << endl; else cout << "mistake" << endl; } return 0; }

5.如果一个数字能表示为p^q(^表示幂运算)且p为一个素数,q为大于1的正整数就称这个数叫做超级素数幂。现在给出一个正整数n,如果n是一个超级素数幂需要找出对应的p,q。 其中n(2 ≤ n ≤ 10^18).
我们首先计算出top=Log(n)/log(2),这里的top就是q所能取得到的最大值,然后我们从2开始枚举到top,每次计算i次根号n,在其为素数的情况下计算i次根号n的i次方是否为n,如果是则输出,否则计算下一次,如果一直计算到top都没有的话则输出No
#include #include using namespace std; long long n; bool isprime(long long x) { long long top = sqrt(x); for (long long i = 2; i <= top; i++) { if (x%i == 0) return false; } return true; } /*a的b次方*/ long long getMi(long long a, long long b) { long long base = a; long long ans = 1; while (b) { if (b % 2 == 1) { ans *= base; } base = base*base; b /= 2; } return ans; } int main() { while (cin >> n) { long long top = log10(n) / log10(2); bool key = false; for (int i = 2; i <= top; i++) { int base = pow(n, 1.0 / i); if (isprime(base)) { long long sum = getMi(base, i); if (sum == n) { cout << base << " " << i << endl; key = true; break; } } } if (key == false) cout << "No" << endl; } return 0; }

6.给出一个正整数N和长度L,找出一段长度大于等于L的连续非负整数,他们的和恰好为N。答案可能有多个,我我们需要找出长度最小的那个。
例如 N = 18 L = 2:
5 + 6 + 7 = 18
3 + 4 + 5 + 6 = 18
都是满足要求的,但是我们输出更短的 5 6 7
几个连续的数排列在一起形成了类似梯形的样子,如下:(矩形的高表示其数值的大小)
牛客网2017年校招全国统一模拟笔试(第一场)编程题集合
文章图片

那么我们先将上部分虚线圈起来的部分删除,则变为几个相等的值,取出上三角之后,如果可以分为L个相等的数,则成立,否则L++
#include using namespace std; int n, l; int main() { while (cin >> n >> l) { bool key = false; for (int i = l; i <= 100; i++) { if ((n - (i*(i - 1) / 2)) / i>=0 && (n - (i*(i - 1) / 2)) % i == 0) { key = true; for (int j = (n - (i*(i - 1) / 2)) / i, k = 0; k < i; k++, j++) { if (k == 0) cout << j; else cout << " " << j; } cout << endl; break; } } if (key == false) cout << "No" << endl; } return 0; }

7.牛牛新买了一本算法书,算法书一共有n页,页码从1到n。牛牛于是想了一个算法题目:在这本算法书页码中0~9每个数字分别出现了多少次?
从1~9这9个数字的计算我们可以找到如下规律(以下除0以外全部以1为基数)
(1)当这一位比要找的数字大时:直接求(高位+1)*base
例如12213中,我们找百位的1,则百位出现1的情况为100~199,1100~1199,2100~2199,…..,11100~11199,12100~12199,一共1300个,刚到等于高位数字+1再乘以当前位数,即(12+1)*100;
(2)当这一位比要找的数字小时:直接求(高位)*base
例如12013中,我们找百位的1,则百位出现1的情况为100~199,1100~1199,2100~2199,…..,11100~11199,一共1200个,刚到等于高位数字再乘以当前位数,即12*100;
(3)当这一位等于要找的数字时:
例如12113中,我们找百位的1,则百位出现1的情况为100~199,1100~1199,2100~2199,…..,11100~11199,12100~12199,一共1200个,刚到等于高位数字再乘以当前位数,即12*100; 除了这些数字以外,还有12100~12113这14个数字,即低位数+1,即13+1.
#include using namespace std; int getNum(int n, int x) { int cur=n,high,low,tem; int sum = 0; for (int base = 1; cur; base *= 10,cur/=10) { tem = cur % 10; high = n / (base*10); low = n % (base); if (x == 0) { if (high) high--; else break; } sum += base*high; if (tem > x) { sum += base; } else if (tem == x) { sum += low +1; } } return sum; } int main() { int n; while (cin >> n) { for (int i = 0; i < 10; i++) if (i == 0) printf("%d", getNum(n, i)); else printf(" %d", getNum(n, i)); printf("\n"); } return 0; }

【牛客网2017年校招全国统一模拟笔试(第一场)编程题集合】8.牛牛正在挑战一款名为01翻转的游戏。游戏初始有A个0,B个1,牛牛的目标就是把所有的值都变为1,每次操作牛牛可以任意选择恰好K个数字,并将这K个数字的值进行翻转(0变为1,1变为0)。牛牛如果使用最少的操作次数完成这个游戏就可以获得奖品,牛牛想知道最少的操作次数是多少?
例如:A = 4 B = 0 K = 3
0000 -> 1110 -> 1001 -> 0100 -> 1111
需要的最少操作次数为4
我们的主题思路采用BFS,因为题目中对于进行反转的数字可以随意选择,且最终的目的是将所有的数字都反转为1,因此我们只需要记录0的个数即可,当0的个数为0时即达到
#include #include #include using namespace std; int a, b, k; bool vis[200005]; struct node { int a_num, b_num, step; node() { step = 0; } }; queue q; int main() { while (cin >> a >> b >> k) { if (a == 0) { cout << 0 << endl; continue; } else if (a + b < k) { cout << -1 << endl; continue; } else if (a == k) { cout << 1 << endl; continue; } while (!q.empty()) q.pop(); node cur,tem; cur.a_num = a; cur.b_num = b; memset(vis, false, sizeof(vis)); q.push(cur); vis[cur.a_num] = true; bool key = false; while (!q.empty()) { cur = q.front(); q.pop(); if (cur.a_num == 0) { cout << cur.step << endl; key = true; break; } for (int i = k; i > 0; i--) { tem = cur; if (tem.a_num >= i && tem.b_num>=(k-i)) { tem.a_num += k-i-i; tem.b_num += i - (k - i); tem.step++; if (vis[tem.a_num] == false) { vis[tem.a_num] = true; q.push(tem); } } } } if (key == false) cout << -1 << endl; } return 0; }

    推荐阅读