您的位置:首页 > 编程语言

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

2017-03-08 14:54 656 查看
原题链接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<iostream>
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<iostream>
#include<map>
#include<string>
using namespace std;
int n;
map<string, int> 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<iostream>
#include<string>
using namespace std;
int main()
{
int count = 0;
string str1;
string str2;
while (cin >> str1 >> str2)
{
for (int i = 0; i<str1.length(); i++)
{
if (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<iostream>
#include<map>
#include<string>
#include<algorithm>
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<iostream>
#include<cmath>
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

几个连续的数排列在一起形成了类似梯形的样子,如下:(矩形的高表示其数值的大小)



那么我们先将上部分虚线圈起来的部分删除,则变为几个相等的值,取出上三角之后,如果可以分为L个相等的数,则成立,否则L++

#include<iostream>
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<iostream>
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;
}


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<iostream>
#include<queue>
#include<cstring>
using namespace std;
int a, b, k;
bool vis[200005];
struct node {
int a_num, b_num, step;
node() {
step = 0;
}
};
queue<node> 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_
a632
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: