zoukankan      html  css  js  c++  java
  • 2017牛客网校招模拟第三场笔试编程题

     2017牛客网校招模拟第三场笔试编程题

    题目来源:https://www.nowcoder.com/test/5217106/summary

    1.变换次数

    牛牛想对一个数做若干次变换,直到这个数只剩下一位数字。变换的规则是:将这个数变成 所有位数上的数字的乘积。比如285经过一次变换后转化成2*8*5=80.

    问题是,要做多少次变换,使得这个数变成个位数。

    输入描述:

    输入一个整数。小于等于2,000,000,000。

    输出描述:

    输出一个整数,表示变换次数。

    输入例子:

    285

    输出例子:

    2

     分析:

    直接暴力计算即可。

     1 #include<iostream>
     2 using namespace std;
     3 int main()
     4 {
     5     int num, count, tmp;
     6     count = 0;
     7     cin >> num;
     8     while (num > 9)
     9     {
    10         tmp = 1;
    11         for (; num; num = num / 10)
    12         {
    13             tmp = tmp*(num % 10);
    14         }
    15         num = tmp;
    16         count++;
    17     }
    18     cout << count << endl;
    19     return 0;
    20 }

     

    2. 神奇数

    给出一个区间[a, b],计算区间内“神奇数”的个数。

     神奇数的定义:存在不同位置的两个数位,组成一个两位数(且不含前导0),且这个两位数为质数。

     比如:153,可以使用数字3和数字1组成13,13是质数,满足神奇数。同样153可以找到31和53也为质数,只要找到一个质数即满足神奇数。

    输入描述:

    输入为两个整数a和b,代表[a, b]区间 (1 ≤ a ≤ b ≤ 10000)。

    输出描述:

    输出为一个整数,表示区间内满足条件的整数个数

    输入例子:

    11 20

    输出例子:

    6

     分析:

    对区间内的数进行枚举,然后按照题目要求的性质进行判断即可。

     1 #include<iostream>
     2 using namespace std;
     3 bool isprime(int n) //判断是否为质数
     4 {
     5     for (int i = 2; i * i <= n; i++) 
     6     {
     7         if (n % i == 0) 
     8             return false;
     9     }
    10     return true;
    11 }
    12 
    13 bool MagicNum(int m) //判断是否为神奇数
    14 {
    15     int cnt[10];
    16     memset(cnt, 0, sizeof(cnt));
    17     while (m) 
    18     {
    19         cnt[m % 10]++;
    20         m /= 10;
    21     }
    22     for (int i = 1; i < 10; i++) 
    23     {
    24         for (int j = 1; j < 10; j++) 
    25         {
    26             if (i != j && cnt[i] && cnt[j]) 
    27             {
    28                 if (isprime(i * 10 + j)) 
    29                     return true;
    30             }
    31             else if (i == j && cnt[i] >= 2) 
    32             {
    33                 if (isprime(i * 10 + j)) 
    34                     return true;
    35             }
    36         }
    37     }
    38     return false;
    39 }
    40 
    41 int main()
    42 {
    43     int a, b ,count;
    44     count = 0;
    45     cin >> a >> b;
    46     for (int i = a; i <= b; i++) //对区间的数进行枚举
    47     {
    48         if (MagicNum(i))    //调用函数,进行判断,函数返回true或者false
    49             count++;
    50     }
    51     cout << count << endl;  //输出结果
    52     return 0;
    53 }

     

    3. 添加字符

    牛牛手里有一个字符串A,羊羊的手里有一个字符串B,B的长度大于等于A,所以牛牛想把A串变得和B串一样长,这样羊羊就愿意和牛牛一起玩了。

     而且A的长度增加到和B串一样长的时候,对应的每一位相等的越多,羊羊就越喜欢。比如"abc"和"abd"对应相等的位数为2,为前两位。

     牛牛可以在A的开头或者结尾添加任意字符,使得长度和B一样。现在问牛牛对A串添加完字符之后,不相等的位数最少有多少位?

    输入描述:

    第一行为字符串A,第二行为字符串B,A的场地小于等于B的长度,B的长度小于等于50.字符均为小写字母。

    输出描述:

    输出一个整数表示A串添加完字符之后,不相等的位数最少有多少位?

    输入例子:

    abe

    cabc

    输出例子:

    1

    分析:

    情况分为两种:1.A的长度小于B的长度     2.A的长度等于B的长度
     当小于时,就枚举B串的一个偏移量,然后枚举维护最小的不相等的位数。
    当等于时,就直接对比就好了。

     1 #include<iostream>
     2 #include<string>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     string a, b;
     8     cin >> a >> b;
     9     int aLength = a.size(), bLength = b.size();
    10     if (aLength < bLength)
    11     {
    12         int ans = 1e9;
    13         for (int i = 0; i + aLength <= bLength; i++)
    14         {
    15             int cnt = 0;
    16             for (int j = 0; j < aLength; j++)
    17             {
    18                 if (a[j] != b[i + j]) 
    19                     cnt++;
    20             }
    21             if (cnt < ans) 
    22             {
    23                 ans = cnt;
    24             }
    25         }
    26         cout << ans << endl;
    27         return 0;
    28     }
    29     else {
    30         int cnt = 0;
    31         for (int j = 0; j < aLength; j++)
    32         {
    33             if (a[j] != b[j]) 
    34                 ++cnt;
    35         }
    36         cout << cnt << endl;
    37     }
    38     return 0;
    39 
    40 }

     

    4. 数组变换

    牛牛有一个数组,里面的数可能不相等,现在他想把数组变为:所有的数都相等。问是否可行。

     牛牛可以进行的操作是:将数组中的任意一个数改为这个数的两倍。

     这个操作的使用次数不限,也可以不使用,并且可以对同一个位置使用多次。

    输入描述:

    输入一个正整数N (N <= 50)

    接下来一行输入N个正整数,每个数均小于等于1e9.

    输出描述:

    假如经过若干次操作可以使得N个数都相等,那么输出"YES", 否则输出"NO"

    输入例子:

    2

    1 2

    输出例子:

    YES

    分析:

    把数组每一个元素都除以2,直到它为奇数。如果此时数组每个元素都一样,满足条件,输出YES

     1 #include<iostream>
     2 #include<string>
     3 using namespace std;
     4 
     5 int num[55];
     6 int main() 
     7 {
     8     int n;
     9     cin >> n;
    10     for (int i = 0; i < n; i++) 
    11         cin >> num[i];
    12     string res = "YES";
    13     for (int i = 0; i < n; i++) 
    14     {
    15         while (!(num[i] & 1))
    16             num[i] >>= 1;
    17     }
    18     for (int i = 1; i < n; i++) 
    19     {
    20         if (num[i] != num[0]) 
    21             res = "NO";
    22     }
    23     cout << res << endl;
    24     return 0;
    25 }

     

    5. 排序子序列

    牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列.

    如样例所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分为2个排序子序列,所以输出2

    输入描述:

    输入的第一行为一个正整数n(1 ≤ n ≤ 10^5)

    第二行包括n个整数A_i(1 ≤ A_i ≤ 10^9),表示数组A的每个数字。

    输出描述:

    输出一个整数表示牛牛可以将A最少划分为多少段排序子序列

    输入例子:

    6

    1 2 3 2 2 1

    输出例子:

    2

    分析:

    考虑序列A_1, A_2, . . . , A_i是一个单调的序列.显然如果对于j < i把序列分为A_1, A_2. . . A_j 和 A_j+1, A_j+2, . . . , A_i 两个部分不会使问题变得更优.

    于是我们可以贪心的去重复下面过程: 1、 从序列中找出最长的单调连续子序列 2、 删除找出的最长的单调连续子序列

    这里的单调序列包括非递增和非递减,而判断子序列是否单调的时候,注意处理等于的情况。

     1 #include<iostream>
     2 #include<vector>
     3 using namespace std;
     4 
     5 int main() 
     6 {
     7     int n;
     8     cin >> n;
     9     vector <int> A;
    10     int ans = 1;
    11     for (int i = 0; i < n; ++i) 
    12     {
    13         int x;
    14         cin >> x;
    15         if (A.size() <= 1)
    16             A.push_back(x);
    17         else 
    18         {
    19             if (A[0] <= A.back() && A.back() <= x)
    20                 A.push_back(x);
    21             else if (A[0] >= A.back() && A.back() >= x)
    22                 A.push_back(x);
    23             else 
    24             {
    25                 ans++;
    26                 A.clear();
    27                 A.push_back(x);
    28             }
    29         }
    30     }
    31     cout << ans << endl;
    32     return 0;
    33 }

     

    6. 组队竞赛

    牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。

     例如:

    一个队伍三个队员的水平值分别是3,3,3.那么队伍的水平值是3

    一个队伍三个队员的水平值分别是3,2,3.那么队伍的水平值是3

    一个队伍三个队员的水平值分别是1,5,2.那么队伍的水平值是2

    为了让比赛更有看点,牛牛想安排队伍使所有队伍的水平值总和最大。

     如样例所示:

    如果牛牛把6个队员划分到两个队伍

     如果方案为:

    team1:{1,2,5}, team2:{5,5,8}, 这时候水平值总和为7.

    而如果方案为:

    team1:{2,5,8}, team2:{1,5,5}, 这时候水平值总和为10.

    没有比总和为10更大的方案,所以输出10.

    输入描述:

    输入的第一行为一个正整数n(1 ≤ n ≤ 10^5)

    第二行包括3*n个整数a_i(1 ≤ a_i ≤ 10^9),表示每个参赛选手的水平值.

    输出描述:

    输出一个整数表示所有队伍的水平值总和最大值.

    输入例子:

    2

    5 2 8 5 1 5

    输出例子:

    10

    分析:

    对于所有参赛队员,我们把他们的水平值进行逆序排序,然后逐一挨着安排每个队伍,然后计算出队伍水平值总和,即为所求。

     1 #include<iostream>
     2 #include<algorithm>
     3 
     4 using namespace std;
     5 
     6 const int maxn = 300100;
     7 int a[maxn];
     8 
     9 int main() 
    10 {
    11     int n; 
    12     cin >> n;
    13     for (int i = 0; i < 3 * n; i++)
    14         cin >> a[i];
    15     sort(a, a + 3 * n);
    16     long long ans = 0;
    17     for (int i = 0; i < n; i++) 
    18         ans += a[n + 2 * i];
    19     printf("%lld
    ", ans);
    20     return 0;
    21 }

     

    7. 牛牛的数列

    牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。

    输入描述:

    输入包括两行,第一行包括一个整数n(1 ≤ n ≤ 10^5),即数列的长度;

    第二行n个整数a_i, 表示数列中的每个数(1 ≤ a_i ≤ 10^9),以空格分割。

    输出描述:

    输出一个整数,表示最长的长度。

    输入例子:

    6

    7 2 3 1 5 6

    输出例子:

    5

    分析:

    正着枚举记录一下当前位置的连续上升子序列长度,倒着也做一遍。
    最后枚举一个连接点即可。

     1 #include <iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 
     5 const int maxn = 100000 + 5;
     6 const int INF = 0x3f3f3f3f;
     7 
     8 int a[maxn], n;
     9 int pre[maxn], suf[maxn];
    10 int main() {
    11     cin >> n;
    12     for (int i = 1; i <= n; i++) 
    13         scanf_s("%d", a + i);
    14     a[0] = INF, a[n + 1] = INF;
    15     for (int i = 1; i <= n; i++) 
    16         pre[i] = a[i - 1] < a[i] ? pre[i - 1] + 1 : 1;
    17     for (int i = n; i >= 1; i--) 
    18         suf[i] = a[i] < a[i + 1] ? suf[i + 1] + 1 : 1;
    19     int ans = 1;
    20     for (int i = 1; i <= n; i++) 
    21     {
    22         ans = max(ans, pre[i - 1] + 1);
    23         ans = max(ans, suf[i + 1] + 1);
    24         if (a[i + 1] - a[i - 1] >= 2) 
    25             ans = max(ans, pre[i - 1] + suf[i + 1] + 1);
    26     }
    27     printf("%d
    ", ans);
    28     return 0;
    29 }

     

  • 相关阅读:
    ios 数据类型转换 UIImage转换为NSData NSData转换为NSString
    iOS UI 12 block传值
    iOS UI 11 单例
    iOS UI 08 uitableview 自定义cell
    iOS UI 07 uitableviewi3
    iOS UI 07 uitableviewi2
    iOS UI 07 uitableview
    iOS UI 05 传值
    iOS UI 04 轨道和动画
    iOS UI 03 事件和手势
  • 原文地址:https://www.cnblogs.com/lxt1105/p/6934136.html
Copyright © 2011-2022 走看看