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\n", 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\n", ans); 28     return 0; 29 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM