牛客网——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;
}

测试结果如下:

 个人能力有限,欢迎各位博友批评指正!!!

posted @ 2017-03-14 21:33  walanwalan  阅读(365)  评论(0编辑  收藏  举报