牛客网——2017校招第一场编程题汇总
题目来源:
https://www.nowcoder.com/test/question/done?tid=7117012&qid=78086
第一题:好多鱼!
题目描述:
牛牛有一个鱼缸。鱼缸里面已经有n条鱼,每条鱼的大小为fishSize[i] (1 ≤ i ≤ n,均为正整数),牛牛现在想把新捕捉的鱼放入鱼缸。鱼缸内存在着大鱼吃小鱼的定律。经过观察,牛牛发现一条鱼A的大小为另外一条鱼B大小的2倍到10倍(包括2倍大小和10倍大小),鱼A会吃掉鱼B。考虑到这个,牛牛要放入的鱼就需要保证:
1、放进去的鱼是安全的,不会被其他鱼吃掉
2、这条鱼放进去也不能吃掉其他鱼
鱼缸里面已经存在的鱼已经相处了很久,不考虑他们互相捕食。现在知道新放入鱼的大小范围[minSize,maxSize](考虑鱼的大小都是整数表示),牛牛想知道有多少种大小的鱼可以放入这个鱼缸。
输入描述:
输入数据包括3行.
第一行为新放入鱼的尺寸范围minSize,maxSize(1 ≤ minSize,maxSize ≤ 1000),以空格分隔。
第二行为鱼缸里面已经有鱼的数量n(1 ≤ n ≤ 50)
第三行为已经有的鱼的大小fishSize[i](1 ≤ fishSize[i] ≤ 1000),以空格分隔。
输出描述:
输出有多少种大小的鱼可以放入这个鱼缸。考虑鱼的大小都是整数表示
输入例子:
1 12
1
1
输出例子:
3
题目分析:
保证旧的鱼不吃新加入的鱼,新加入的鱼不吃旧的鱼,满足这两个条件num++。
完整测试代码:
#include<vector> #include<algorithm> #include<functional> #include<iostream> using namespace std; int main() { int minSize, maxSize; int n; while (cin >> minSize >> maxSize ) { //键入最小尺寸、最大尺寸、已经有鱼的数目 cin >> n; vector<int> fishSize; int num = 0; for (int i = 0; i < n; i++) { //将已经存在的鱼的尺寸进行压栈 int fish; cin >> fish; fishSize.push_back(fish); } for (int i = minSize; i <= maxSize; i++) { bool flag = true; for (int j = 0; j < fishSize.size(); j++) { //保证旧的鱼不吃新的鱼 if ((fishSize[j]) / i >= 2 && (fishSize[j]) / i <= 10) { if ((fishSize[j]) / i == 10 && (fishSize[j]) % i != 0) { continue; } flag = false; break; } //保证新的鱼不吃旧的鱼 if (i / fishSize[j] >= 2 && i / fishSize[j] <= 10) { if (i / fishSize[j] == 10 && i % fishSize[j] != 0) { continue; } flag = false; break; } } if (flag == true) { num++; } } cout << num << endl; } return 0; }
调试结果如下:
第二题、循环单词
题目描述:
如果一个单词通过循环右移获得的单词,我们称这些单词都为一种循环单词。 例如:picture 和 turepic 就是属于同一种循环单词。 现在给出n个单词,需要统计这个n个单词中有多少种循环单词。
输入描述:
输入包括n+1行:
第一行为单词个数n(1 ≤ n ≤ 50)
接下来的n行,每行一个单词word[i],长度length(1 ≤ length ≤ 50)。由小写字母构成
输出描述:
输出循环单词的种数
输入例子:
5
picture
turepic
icturep
word
ordw
输出例子:
2
完整代码如下:
#include <iostream> #include <string> #include <vector> using namespace std; int main() { int number, count = 0, checked[50] = { 0 }; //count为答案,check为标记数组,表示对应位置的string已经被操作过。 string sInput[50]; cin >> number; for (auto i = 0; i < number; i++) { cin >> sInput[i]; } for (auto i = 0; i < number; i++) { if (checked[i] != 0) //如果该string已经被操作过,则跳过该位置。 { break; } string sCompare1 = sInput[i] + sInput[i];//将未标记的string加长一倍 checked[i] = 1;//该string位置标记 for (auto j = i + 1; j < number; j++) //从加倍的string向后比较 { if (checked[j] == 0 && sInput[i].size() == sInput[j].size() && sCompare1.find(sInput[j], 0) != string::npos) //只修改了这里,上一版这里是错的,find返回的是sInput[j]位置,可以为0。 //没找到返回string::npos。 { checked[j] = 1; count++;//将答案加1 } } } cout << count <<endl; }
测试结果如下:
第三题、DNA合成
题目描述:
DNA分子是以4种脱氧核苷酸为单位连接而成的长链,这4种脱氧核苷酸分别含有A,T,C,G四种碱基。碱基互补配对原则:A和T是配对的,C和G是配对的。如果两条碱基链长度是相同的并且每个位置的碱基是配对的,那么他们就可以配对合成为DNA的双螺旋结构。现在给出两条碱基链,允许在其中一条上做替换操作:把序列上的某个位置的碱基更换为另外一种碱基。问最少需要多少次让两条碱基链配对成功
输入描述:
输入包括一行:
包括两个字符串,分别表示两条链,两个字符串长度相同且长度均小于等于50。
输出描述:
输出一个整数,即最少需要多少次让两条碱基链配对成功
输入例子:
ACGT TGCA
输出例子:
0
完整代码如下:
#include<iostream> #include<string> using namespace std; int main() { int count = 0; char s[102]; cin.getline (s,102); size_t l = strlen(s); int len = l / 2; if (s[len] == ' ') { for (int i = 0; i < len; i++) { int j = len + 1 + i; if ((s[i] == 'A'&&s[j] == 'T') || (s[i] == 'T'&&s[j] == 'A') || (s[i] == 'C'&&s[j] == 'G') || (s[i] == 'G'&&s[j] == 'C')) { } else { count++; } } } else cout << "错误输入" << endl; cout << count << endl; return 0; }
测试结果如下:
第四题、连续整数
题目描述:
牛牛的好朋友羊羊在纸上写了n+1个整数,羊羊接着抹除掉了一个整数,给牛牛猜他抹除掉的数字是什么。牛牛知道羊羊写的整数神排序之后是一串连续的正整数,牛牛现在要猜出所有可能是抹除掉的整数。例如:
10 7 12 8 11 那么抹除掉的整数只可能是9
5 6 7 8 那么抹除掉的整数可能是4也可能是9
输入描述:
输入包括2行:
第一行为整数n(1 <= n <= 50),即抹除一个数之后剩下的数字个数
第二行为n个整数num[i] (1 <= num[i] <= 1000000000)
输出描述:
在一行中输出所有可能是抹除掉的数,从小到大输出,用空格分割,行末无空格。如果没有可能的数,则输出mistake
输入例子:
2
3 6
输出例子:
mistake
完整代码如下:
#include<iostream> #include<algorithm> #include<string> using namespace std; int main() { int n; cin >> n; //输入整数n,表示剩余数的多少 long int num[100] ; for (int i = 0; i < n; i++) { cin >> num[i];//依次键入剩余的n个数字,并存放在num数组中 } sort(num, num + n); int j = 0; bool flag = false; int count = 0; while ( j < n - 1) { if (num[j + 1] - num[j] > 2) { cout << "mistake" << endl; flag = true; } if (num[j + 1] - num[j] == 2) { count++; flag = true; } j++; } if (count == 1) { for (int i = 0; i < n - 1; i++) { if (num[i + 1] - num[i] == 2) cout << num[i] + 1 << endl; } } else if (count!=0) cout << "mistake" << endl; if (flag == false) { if (num[0] == 1) cout << num[n - 1] + 1 << endl; else cout << num[0] - 1 << " " << num[n - 1] + 1 << endl; } return 0; }
测试结果如下:
第五题、超级素数幂
题目描述:
如果一个数字能表示为p^q(^表示幂运算)且p为一个素数,q为大于1的正整数就称这个数叫做超级素数幂。现在给出一个正整数n,如果n是一个超级素数幂需要找出对应的p,q。
输入描述:
输入一个正整数n(2 ≤ n ≤ 10^18)
输出描述:
如果n是一个超级素数幂则输出p,q,以空格分隔,行末无空格。
如果n不是超级素数幂,则输出No
输入例子:
27
输出例子:
3 3
完整代码如下:
#include<iostream> #include<cmath> using namespace std; long long n; long long calc(long long m, int n)//计算吗m的n次方 { return n == 0 ? 1 : calc(m, n - 1) * m; } bool check(long long n) //判断是否是素数 { long long tmp = sqrt(n); for (long long i = 2; i <= tmp; i++){ if (n % i == 0) return false; } return true; } int main(){ cin >> n; int flag = 1; for (int i = 2;; i++) { double tmp = pow(n, 1.0 / i);//开i次根号 if (tmp < 2.0) break; if (calc((long long)(tmp + 0.1), i) == n && check((long long)(tmp + 0.1))) { flag = 0; cout << (int)(tmp + 0.1) << " " << i << endl; } } if (flag) cout << "No" << endl; }
测试结果如下:
第六题、序列和
题目描述:
给出一个正整数N和长度L,找出一段长度大于等于L的连续非负整数,他们的和恰好为N。答案可能有多个,我我们需要找出长度最小的那个。
例如 N = 18 L = 2:
5 + 6 + 7 = 18
3 + 4 + 5 + 6 = 18
都是满足要求的,但是我们输出更短的 5 6 7
输入描述:
输入数据包括一行:
两个正整数N(1 ≤ N ≤ 1000000000),L(2 ≤ L ≤ 100)
输出描述:
从小到大输出这段连续非负整数,以空格分隔,行末无空格。如果没有这样的序列或者找出的序列长度大于100,则输出No
输入例子:
18 2
输出例子:
5 6 7
完整代码如下:
#include <iostream> #include<vector> using namespace std; vector <int> sequence(int S, int L0) { vector<int> R; for (int L = L0; L <= 100; L++) { if (S - L * (L - 1) / 2 >= 0 && (S - L * (L - 1) / 2) % L == 0) { int A = (S - L * (L - 1) / 2) / L; for (int i = 0; i < L; i++) R.push_back(A + i); return R; } } return R; } int main() { int S, L; cin >> S >> L; vector<int> ans; ans = sequence(S, L); if (ans.size() == 0) cout << "No" << endl; else { for (int i = 0; i < ans.size(); i++) { i == 0 ? cout << ans[i] : cout << " " << ans[i]; } } return 0; }
测试结果如下:
第七题、页码统计
题目描述:
牛牛新买了一本算法书,算法书一共有n页,页码从1到n。牛牛于是想了一个算法题目:在这本算法书页码中0~9每个数字分别出现了多少次?
输入描述:
输入包括一个整数n(1 ≤ n ≤ 1,000,000,000)
输出描述:
输出包括一行10个整数,即0~9这些数字在页码中出现的次数,以空格分隔。行末无空格。
输入例子:
999
输出例子:
189 300 300 300 300 300 300 300 300 300
完整代码如下:
#include <iostream> #include<vector> using namespace std; vector<int> solve(int n) { vector<int> res(10, 0); if (!n) return res; if (n % 10 < 9) { res = solve(n - 1); while (n) { res[n % 10]++; n /= 10; } return res; } res = solve(n / 10); for (int i = 0; i < 10; i++) res[i] = res[i] * 10 + n / 10 + (i > 0); return res; } int main() { int n; cin >> n; vector<int> ans = solve(n); for (int i = 0; i < ans.size(); i++) { i == 0 ? cout << ans[i] : cout << " " << ans[i]; } return 0; }
测试结果如下:
个人能力有限,欢迎各位博友批评指正!!!