牛客网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<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_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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值