1. 程式人生 > >PAT乙級(Basic Level)真題訓練

PAT乙級(Basic Level)真題訓練

寫在前面:
PAT冬季賽馬上就要開始了!​​這一次先報一個乙級衝鴨!我感Jio乙級裡面還是有蠻多水題的,也有些題雖然看上去是水題,但是真正用程式碼實現起來的話會卡你那麼一下,比如第5題數素數真的神打臉。

天上不會掉餡餅的,好好學習,努力奮鬥才能夢想成真。

1. D進位制的A + B(20)

題目描述:

輸入兩個非負10進位制整數A和B(<= 230-1),輸出A + B的D(1 <D <= 10)進位制數。

輸入描述:

輸入在一行中依次給出3個整數A,B和D。

輸出描述:

輸出A + B的d進位制數。

輸入例子:

123 456 8

輸出例子:

1103

解題思路: 

首先,這道題看上去很簡單,但是用程式碼實現起來發現有點難受啊。幸虧資料結構沒白學,我用了一個堆疊。先令C = A + B如果Ç等於0,就直接輸出0,否則對C進行進位制轉換。這道題主要考察的應該就是將十進位制的C轉換成D進位制。先把C對D的餘數推入棧中,然後C除以D的值賦給C,最後根據堆疊“後進先出”的規則輸出C對D的餘數,也就得到了D進位制下的C。

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 int main()
 5 {
 6     int a,b,d;
7 cin >> a >> b >> d; 8 stack<int> s; 9 int c = a+b; 10 if(c == 0) 11 { 12 cout << 0; 13 } 14 while(c!=0) 15 { 16 s.push(c%d); 17 c /= d; 18 } 19 while(!s.empty()) 20 { 21 cout << s.top();
22 s.pop(); 23 } 24 return 0; 25 }

2. A + B和C(15)

題目描述:

給定區間[-2的31次方,2的31次方]內的3個整數A,B和C,請判斷A + B是否大於C。

輸入描述:

輸入第1行給出正整數T(<= 10),是測試用例的個數。隨後給出Ť組測試用例,每組佔一行,順序給出A,B和C.整數間以空格分隔。

輸出描述:

對每組測試用例,在一行中輸出“Case #X:true”如果A + B> C,否則輸出“Case #X:false”,其中X是測試用例的編號(從1開始)。

輸入例子:

4
1 2 3
2 3 4
2147483647 0 2147483646
0 -2147483648 -2147483647

輸出例子:

Case #1: false
Case #2: true
Case #3: true
Case #4: false

解題思路: 

首先看到這道題給定的區間是[-2的31次方,2的31次方],直接無腦用Python的。這段程式碼中最秀的地方就是這個A,B,C =map(int,input().split())啦!map()函式的用法如下:map(func,seq1 [,seq2,...])第一個引數接受一個函式名,後面的引數接受一個或多個可Python的函式程式設計中的map()函式是將FUNC作用於SEQ中的每一個元素,並將所有的呼叫的結果作為一個列表返回。

AC程式碼: 

1 t = eval(input())
2 for i in range(1,t+1):
3     a,b,c=map(int,input().split())
4     if a+b>c:
5         print("Case #{}: true".format(i))
6     else:
7         print("Case #{}: false".format(i))

 

3.查驗身份證(15)

題目描述:

一個合法的身份證號碼由17位地區,日期編號和順序編號加1位校驗碼組成校驗碼的計算規則如下:
首先對前17位數字加權求和,權重分配為:{7,9, 10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然後將計算的和對11取模得到值Z者除外;最後按照以下關係對應ž值與校驗碼M的值:
Z:0 1 2 3 4 5 6 7 8 9 10
M:1 0 X 9 8 7 6 5 4 3 2
現在給定一些身份證號碼,請你驗證校驗碼的有效性,並輸出有問題的號碼。

輸入描述:

輸入第一行給出正整數N(<= 100)是輸入的身份證號碼的個數。隨後N行,每行給出1個18位身份證號碼。

輸出描述:

按照輸入的順序每行輸出1個有問題的身份證號碼。這裡並不檢驗前17位是否合理,只檢查前17位是否全為數字且最後1位校驗碼計算準確。如果所有號碼都正常,則輸出“All passed”。

輸入例子:

4
320124198808240056
12010X198901011234
110108196711301866
37070419881216001X

輸出例子:

12010X198901011234
110108196711301866
37070419881216001X

解題思路: 

首先,這個題目看起我有點懵逼,真的題目都看了3,4遍。好好縷了下思路之後,先建立倆個數組分別用來存放權值分配和校驗碼M.然後取消CIN與標準輸入的同步壓壓驚,真的怕TLE,畢竟要對若干個18位數的身份證每一位進行校驗。立個標誌=真,如果到最後,標誌還是為真,表明所有的身份證號碼都正常,輸出“All passed”。然後isTrue用來判斷每一個身份證號的前17位是否全為數字,若不是數字則isTrue和flag都變成false,用sum來計算身份證號號的每一位數和它所佔的權值的乘積之和,將計算出來的總和對11取模得到值Z,根據題意可知,可以根據ž值來找到對應的校驗碼中號的值,若IsTrue運算為真但校驗碼中號和身份證最後一位不相等,這個身份證號也是錯誤的,需要對錯誤的身份證號進行輸出。

AC程式碼: 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 int weight[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
 5 char M[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
 6  
 7 int main()
 8 {
 9     ios::sync_with_stdio(false);
10     int n;
11     cin >> n;
12     string ID;
13     bool flag = true;
14     for (int i = 0; i < n; i++)
15     {
16         int sum = 0;
17         bool isTrue = true;
18         cin >> ID;
19         for(int j = 0; j < 17; j++)
20         {
21             if(ID[j]<'0'||ID[j]>'9')
22             {
23                 cout << ID << endl;
24                 flag = false;
25                 isTrue = false;
26                 break;
27             }
28             sum += (ID[j]-'0')*weight[j];
29         }
30         int z = sum%11;
31         if(ID[17]!=M[z] && isTrue)
32         {
33             flag = false;
34             cout << ID << endl;
35         }
36     }
37     if(flag)
38     {
39         cout << "All passed" << endl;
40     }
41     return 0;
42 }

 4.數字分類(20)

題目描述:

給定一系列正整數,請按要求對數字進行分類,並輸出以下5個數字:

A1 = 能被5整除的數字中所有偶數的和;
A2 = 將被5除後餘1的數字按給出順序進行交錯求和,即計算n1-n2+n3-n4...;
A3 = 被5除後餘2的數字的個數;
A4 = 被5除後餘3的數字的平均數,精確到小數點後1位;
A5 = 被5除後餘4的數字中最大數字。

輸入描述:

每個輸入包含1個測試用例。每個測試用例先給出一個不超過1000的正整數N,隨後給出N個不超過1000的待分類的正整數。數字間以空格分隔。

輸出描述:

對給定的N個正整數,按題目要求計算A1~A5並在一行中順序輸出。數字間以空格分隔,但行末不得有多餘空格。

若其中某一類數字不存在,則在相應位置輸出'N'。

輸入例子:

13 1 2 3 4 5 6 7 8 9 10 20 16 18

輸出例子:

30 11 2 9.7 9

解題思路: 

首先,根據題意可知這是一道水題,真的水得不能再水了,直接按著題目來就求A1,A2,A3,A4,A5就行啦,整除5的時候可以用開關,但是我用的的if-else。

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 int main()
 5 {
 6     int n;
 7     cin >> n;
 8     int a[n];
 9     for (int i = 0; i < n; i++)
10     {
11         cin >> a[i];
12     }
13     int A1 = 0,A2 = 0,A3 = 0,A5 = -1e5,count_A4 = 0;
14     double A4;
15     int flag = 1;
16     bool T1 = false,T2 = false,T3 = false,T4 = false,T5 = false;
17     for (int i = 0; i < n; i++)
18     {
19         if(a[i]%5==0 && a[i]%2==0)  //A1是能被5整除的所有偶數的和
20         {
21             A1 += a[i];
22             T1 = true;
23         }
24         if(a[i]%5==1)  //A2是將被5除後餘1的數字按給出順序進行交錯求和
25         {
26             A2 += a[i]*flag;
27             flag = -flag;
28             T2 = true;
29         }
30         if(a[i]%5==2)   //A3是被5除後餘2的數字的個數
31         {
32             A3++;
33             T3 = true;
34         }
35         if(a[i]%5==3) //A4是被5除後餘3的數字的平均數,精確到小數點後1位
36         {
37             A4 += a[i];
38             count_A4++;
39             T4 = true;
40         }
41         if(a[i]%5==4) //A5是被5除後餘4的數字中最大數字
42         {
43             if(a[i] > A5)
44             {
45                 A5 = a[i];
46             }
47             T5 = true;
48         }
49     }
50     if(T1)
51     {
52         cout << A1 << " ";
53     }
54     else
55     {
56         cout << 'N' << " ";
57     }
58     if(T2)
59     {
60         cout << A2 << " ";
61     }
62     else 
63     {
64         cout << 'N' << " ";
65     }
66     if(T3)
67     {
68         cout << A3 << " ";
69     }
70     else
71     {
72         cout << 'N' << " ";
73     }
74     if(T4)
75     {
76         printf("%.1lf ",A4/count_A4);
77     }
78     else
79     {
80         cout << 'N' << " ";
81     }
82     if(T5)
83     {
84         cout << A5 << endl;
85     }
86     else
87     {
88         cout << 'N' << endl;
89     }
90     return 0;
91 }

5.數素數(20)

題目描述:

令Pi表示第i個素數。現任給兩個正整數M <= N <= 10000,請輸出PM到PN的所有素數。

輸入描述:

輸入在一行中給出中號和N,其間以空格分隔。

輸出描述:

輸出從PM到PN的所有素數,每10個數字佔1行,其間以空格分隔,但行末不得有多餘空格。

輸入例子:

5 27

輸出例子:

>11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103

解題思路: 

 首先根據題意可知這是一道水題,不就是建立一個求素數的函式,然後用for迴圈對第m個素數到第n個素數進行輸出嗎?(尷尬地劃掉第一句話,有個測試用例錯誤打我臉了)當輸入10000 10000這個測試用例時,我寫的第一個演算法有bug,它會直接輸出0,而第10000個素數是104729,這才是期待的輸出。我把int改成long long型也無濟於事,懵逼了。與其花費時間去修改這個bug,不如推翻重來換一個思路,然後我寫了一種用優先佇列的演算法,測試用例全部AC,哈哈哈哈 資料結構還是沒白學。首先自定義一個isPrime(int n)的函式用來判斷一個數是否為素數,然後再主函式中用count來記錄素數的個數,當count在[m,n]這個範圍內時,對這個素數進行入隊操作。為了輸出格式和題目要求相符,先立一個flag,第m個素數一輸出就把flag改掉,然後先輸出空格再輸出素數,這樣就可以避免最後的第n個素數後面還出現空格而導致格式錯誤的情況。

AC程式碼:打臉程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 bool isPrime(int n)
 5 {
 6     for(int i=2;i<=sqrt(n);i++)
 7     {
 8         if(n%i==0)
 9         {
10             return false;
11         }
12     }
13     return true;
14 }
15  
16 int main()
17 {
18     int m,n;
19     cin >> m >> n;
20     int a[10000];
21     for(int i=1, j=0;i<=10000;i++)
22     {
23         if(isPrime(i))
24         {
25             a[j++] = i;
26         }
27     }
28     bool flag = true;
29     int count = 0;
30     for (int i = m; i <= n; ++i)
31     {
32         if(flag)
33         {
34             cout << a[i];
35             flag = false;
36         }
37         else
38         {
39             cout <<  " " << a[i];
40         }
41         count++;
42         if(count%10 == 0)
43         {
44             flag = true;
45             cout << endl;
46         }
47     }
48     return 0;
49 }

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 bool isPrime(int n)
 5 {
 6     if(n<=1) return false;
 7     for(int i=2;i<=sqrt(n);i++)
 8     {
 9         if(n%i==0)
10         {
11             return false;
12         }
13     }
14     return true;
15 }
16  
17 int main()
18 {
19     int m,n;
20     cin >> m >> n;
21     priority_queue< int, vector<int>, greater<int> > l;   //優先佇列
22     int count = 0;
23     for(int i=1;count<=n;i++)
24     {
25         if(isPrime(i))
26         {
27             count++;
28             if(count>=m && count<=n)
29             {
30                 l.push(i);
31             }
32         }
33     }
34     bool flag = true;
35     count = 0;
36     for (int i = m; i <= n; ++i)
37     {
38         if(flag)
39         {
40             cout << l.top();
41             l.pop();
42             flag = false;
43         }
44         else
45         {
46             cout <<  " " << l.top();
47             l.pop();
48         }
49         count++;
50         if(count%10 == 0)
51         {
52             flag = true;
53             cout << endl;
54         }
55     }
56     return 0;
57 }

6.錘子剪刀布(20)

題目描述:

大家應該都會玩“錘子剪刀布”的遊戲。現給出兩人的交鋒記錄,請統計雙方的勝,平,負次數,並且給出雙方分別出什麼手勢的勝算最大。

輸入描述:

輸入第1行給出正整數N(<= 105),即雙方交鋒的次數。隨後Ñ行,每行給出一次交鋒的資訊,即甲,乙雙方同時給出的的手勢.C代表“錘子“,J代表‘剪刀’,B代表‘布’,第1個字母代表甲方,第2個代表乙方,中間有1個空格。

輸出描述:

輸出第1,2行分別給出甲,乙的勝,平,負次數,數字間以1個空格分隔。第3行給出兩個字母,分別代表甲,乙獲勝次數最多的手勢,中間有1個空格。如果解不唯一,則輸出按字母序最小的解。

輸入例子:

10
C J
J B
C B
B B
B C
C C
C B
J B
B C
J J

輸出例子:

5 3 2
2 3 5
B B

解題思路: 

首先通過題意可知這是一道程式碼量很大的水題。它不僅需要記錄甲乙勝負平的次數,而且需要記錄甲乙獲勝的手勢,然後通過比較來找出獲勝最多的手勢,在不唯一的情況下輸出字母序最小的解。

AC程式碼:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3  
  4 char getMax(int b,int c,int j)
  5 {
  6     if(b!=c&&b!=j&&c!=j)
  7     {
  8         if(b>c&&b>j)
  9         {
 10             return 'B';
 11         }
 12         if(c>b&&c>j)
 13         {
 14             return 'C';
 15         }
 16         if(j>b&&j>c)
 17         {
 18             return 'J';
 19         }
 20     }
 21     else
 22     {
 23         if(b==c&&b>j)
 24         {
 25             return 'B';
 26         }
 27         if(b==c&&b<j)
 28         {
 29             return 'J';
 30         }
 31         if(c==j&&c>b)
 32         {
 33             return 'C';
 34         }
 35         if(c==j&&c<b)
 36         {
 37             return 'B';
 38         }
 39         if(b==j&&b>c)
 40         {
 41             return 'B';
 42         }
 43         if(b==j&&b<c)
 44         {
 45             return 'C';
 46         }
 47         if(b==j&&c==j&&b==c)
 48         {
 49            return 'B';
 50         }
 51     }
 52     return '1';
 53  }
 54  
 55 int main()
 56 {
 57     int n;
 58     cin >> n;
 59     int count_XC=0,count_XJ=0,count_XB=0;
 60     int count_YC=0,count_YJ=0,count_YB=0;
 61     int count_Xwin=0,count_Xlose=0,count_Xequal=0;
 62     for (int i = 0; i < n; ++i)
 63     {
 64  
 65         char X,Y;
 66         cin >> X >> Y;
 67         if(X == Y)
 68         {
 69             count_Xequal++;
 70         }
 71         else
 72         {
 73             bool X_defeat_Y = false;
 74             if((X=='C'&&Y=='J')||(X=='J'&&Y=='B')||(X=='B'&&Y=='C'))
 75             {
 76                 X_defeat_Y = true;
 77             }
 78             if(X_defeat_Y)
 79             {
 80                 switch(X)
 81                 {
 82                     case 'C': count_XC++; break;
 83                     case 'J': count_XJ++; break;
 84                     case 'B': count_XB++; break;
 85                     default : break;
 86                 }
 87                 count_Xwin++;
 88             }
 89             else
 90             {
 91                 switch(Y)
 92                 {
 93                     case 'C': count_YC++; break;
 94                     case 'J': count_YJ++; break;
 95                     case 'B': count_YB++; break;
 96                     default : break;
 97                 }
 98                 count_Xlose++;
 99             }
100         }
101     }
102     cout << count_Xwin << " " << count_Xequal << " " << count_Xlose << endl;
103     cout << count_Xlose << " " << count_Xequal << " " << count_Xwin << endl;
104     int max_X=-1e5,max_Y=-1e5;
105     char maxc_X = getMax(count_XB,count_XC,count_XJ);
106     char maxc_Y = getMax(count_YB,count_YC,count_YJ);
107     cout << maxc_X << " " << maxc_Y << endl;
108     return 0;
109 }

7.個位數統計(15)

題目描述:

給定一個k位整數N = dk-1 * 10k-1 + ... + d1 * 101 + d0(0 <= di <= 9,i = 0,...,k-1,dk-1> 0),請編寫程式統計每種不同的個位數字出現的次數。例如:給定N = 100311,則有2個0,3個1,和1個3。

輸入描述:

每個輸入包含1個測試用例,即一個不超過1000位的正整數N。

輸出描述:

對N中每一種不同的個位數字,以d:M的格式在一行中輸出該位數字d及其在N中出現的次數M.要求按d的升序輸出。

輸入例子:

100311

輸出例子:

0:2
1:3
3:1

解題思路: 

首先,根據題意可知這是一道水題,那麼問題來了,怎麼在寫水題的同時秀一波操作呢?額,我用一個map<char, int>來存放出現過的數字並記錄下出現的次數,然後用for-each迴圈來對map進行遍歷並輸出出現過的數字和出現的次數。

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 int main()
 5 {
 6     string n;
 7     map<char, int> m;
 8     cin >> n;
 9     for(auto i:n)   
10     {
11         m[i]++;
12     }
13     for (auto i:m)
14     {
15         cout << i.first << ":" << i.second << endl;
16     }
17     return 0;
18 }

8.組個最小數(20)

題目描述:

給定數字0-9各若干個你可以以任意順序排列這些數字,但必須全部使用目標是使得最後得到的數儘可能小(注意0不能做首位)例如:。給定兩個0,兩個1,三個5,一個如圖8所示,我們得到的最小的數就是10015558.現給定數字,請編寫程式輸出能夠組成的最小的數。

輸入描述:

每個輸入包含1個測試用例。每個測試用例在一行中給出10個非負整數,順序表示我們擁有數字0,數字1,......數字9的個數。整數間用一個空格分隔0.10個數字的總個數不超過50,且至少擁有1個非0的數字。

輸出描述:

在一行中輸出能夠組成的最小的數。

輸入例子:

2 2 0 0 0 3 0 0 1 0

輸出例子:

10015558

解題思路: 

首先,根據題意可知這是一道水題,第一位數輸出非0的最小值,然後後面的位數直接依次把身下的數字中的最小值輸出,輸出的結果就是最小數。

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define n 10
 4 int main()
 5 {
 6     int a[n];
 7     for (int i = 0; i < n; i++)
 8     {
 9         cin >> a[i];
10     }
11     for(int i = 1; i < n; i++)  //先輸出第一位數
12     {
13         if(a[i])
14         {
15             cout << i;
16             a[i]--;
17             break;
18         }
19     }
20     for(int i = 0; i < n; i++)
21     {
22         while(a[i]--)
23         {
24             cout << i;
25         }
26     }
27     return 0;
28 }

9.程式執行時間(15)

題目描述:

要獲得一個Ç語言程式的執行時間,常用的方法是呼叫標頭檔案time.h中,其中提供了時鐘()函式,可以捕捉從程式開始執行到時鐘()被呼叫時所耗費的時間。這個時間單位是時鐘滴答,即“時鐘打點”。同時還有一個常數CLK_TCK,給出了機器時鐘每秒所走的時鐘打點數。於是為了獲得一個函式f的執行時間,我們只要在呼叫f之前先呼叫時鐘(),獲得一個時鐘打點數C1;在˚F執行完成後再呼叫時鐘(),獲得另一個時鐘打點數C2;兩次獲得的時鐘打點數之差(C2-C1)就是˚F執行所消耗的時鐘打點數,再除以常數CLK_TCK,就得到了以秒為單位的執行時間。

這裡不妨簡單假設常數CLK_TCK為100現給定被測函式前後兩次獲得的時鐘打點數,請你給出被測函式執行的時間。

輸入描述:

輸入在一行中順序給出2個整數C1和C1。注意兩次獲得的時鐘打點數肯定不相同,即C1 <C2,並且取值在[0,107]

輸出描述:

在一行中輸出被測函式執行的時間。執行時間必須按照“hh:mm:ss”(即2位的“時:分:秒”)格式輸出;不足1秒的時間四捨五入到秒。

輸入例子:

123 4577973

輸出例子:

12:42:59

解題思路: 

首先,根據題意可知這是一道水題,真的水得不能再水了,直接求出C1和C2的時間差,然後化成時分秒就行了。

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 int main()
 5 {
 6     int c1,c2;
 7     cin >> c1 >> c2;
 8     int t = round((c2-c1)/100.0);
 9     printf("%02d:%02d:%02d\n",t/3600,t%3600/60,t%60);
10     return 0;
11 }

10.人口普查(20)

題目描述:

某城鎮進行人口普查,得到了全體居民的生日。現請你寫個程式,找出鎮上最年長和最年輕的人。這裡確保每個輸入的日期都是合法的,但不一定是合理的-假設已知鎮上沒有超過200歲的老人,而今天是2014年9月6日,所以超過200歲的生日和未出生的生日都是不合理的,應該被過濾掉。

輸入描述:

輸入在第一行給出正整數N,取值在(0,105);隨後N行,每行給出1個人的姓名(由不超過5個英文字母組成的字串),以及 按“yyyy / MM / DD”(即年/月/日)格式給出的生日。題目保證最年長和最年輕的人沒有並列。

輸出描述:

在一行中順序輸出有效生日的個數,最年長人和最年輕人的姓名,其間以空格分隔。

輸入例子:

5
John 2001/05/12
Tom 1814/09/06
Ann 2121/01/30
James 1814/09/05
Steve 1967/11/20

輸出例子:

3 Tom John

解題思路: 

首先,根據題意可知這個人口普查其實就是2個變數而已嘛,一個name,一個birthday,那就直接建立一個person結構體好了。然後根據題目要求這個島上的人生日在1814/09/06至2014/09/06這個範圍內,接下來直接用for迴圈對輸入進行遍歷來求解在這個範圍內的有效生日並找出最年長和最年輕的人所在的下標就好了。

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 struct person
 5 {
 6     string name,birthday;
 7 };
 8  
 9 int main()
10 {
11     int n;
12     cin >> n;
13     string start = "1814/09/06";
14     string end = "2014/09/06";
15     person p[n];
16     int count=0;
17     bool flag = true;
18     int minIndex,maxIndex;
19     for (int i = 0; i < n; i++)
20     {
21         cin >> p[i].name >> p[i].birthday;
22         if(p[i].birthday>=start && p[i].birthday<=end)
23         {
24             count++;
25             if(flag)
26             {
27                 flag = false;
28                 minIndex = i, maxIndex = i;
29             }
30             else
31             {
32                 if(p[minIndex].birthday>p[i].birthday)
33                 {
34                     minIndex = i;
35                 }
36                 if(p[maxIndex].birthday<p[i].birthday)
37                 {
38                     maxIndex = i;
39                 }
40             }
41         }
42     }
43     cout << count << " " << p[minIndex].name << " " << p[maxIndex].name << endl;
44     return 0;
45 }

11.舊鍵盤(20)

題目描述:

舊鍵盤上壞了幾個鍵,於是在敲一段文字的時候,對應的字元就不會出現。現在給出應該輸入的一段文字,以及實際被輸入的文字,請你列出肯定壞掉的那些鍵。

輸入描述:

輸入在2行中分別給出應該輸入的文字,以及實際被輸入的文字。每段文字是不超過80個字元的串,由字母AZ(包括大,小寫),數字0-9,以及下劃線“ _”(代表空格)組成。題目保證2個字串均非空。

輸出描述:

按照發現順序,在一行中輸出壞掉的鍵。其中英文字母只輸出大寫,每個壞鍵只輸出一次。題目保證至少有1個壞鍵。

輸入例子:

7_This_is_a_test
_hs_s_a_es

輸出例子:

7TI

解題思路: 

首先,根據題意腦子裡冒出一句話“Life is short, use python!”  用for迴圈來遍歷應該輸入的蚊子,如果一個字元是應該輸入的但實際上未被輸入,就用upper()把這個字元轉換成大寫形式存入bad_key這個列表中,接下來就是對bad_key這個列表去重輸出。先利用set()來對bad_key()進行去重,然後再用list()將bad_key()轉換回列表,在完成這個去重操作的同時,用sorted()函式來保留bad_key原有的順序,最後用join把bad_key中所有的元素新增到一個空字串中進行輸出。

AC程式碼:

1 s,a = input(),input()
2 bad_key = [i.upper() for i in s if i not in a]
3 print("".join(sorted(list(set(bad_key)),key=bad_key.index))) 

12. 舊鍵盤打字(20)

題目描述:

舊鍵盤上壞了幾個鍵,於是在敲一段文字的時候,對應的字元就不會出現。現在給出應該輸入的一段文字、以及壞掉的那些鍵,打出的結果文字會是怎樣?

輸入描述:

輸入在2行中分別給出壞掉的那些鍵、以及應該輸入的文字。其中對應英文字母的壞鍵以大寫給出;每段文字是不超過10^5個字元的串。可用的字元包括字母[a-z, A-Z]、數字0-9、以及下劃線“_”(代表空格)、“,”、“.”、“-”、“+”(代表上檔鍵)。題目保證第2行輸入的文字串非空。 注意:如果上檔鍵壞掉了,那麼大寫的英文字母無法被打出。

輸出描述:

在一行中輸出能夠被打出的結果文字。如果沒有一個字元能被打出,則輸出空行。

輸入例子:

7+IE.
7_This_is_a_test.

輸出例子:

_hs_s_a_tst

解題思路: 

 首先,看完題目之後發現它和上一題很相似,還是那句話“Life is short, use python!”  雖然思路也很簡單,但是! 這次的程式碼有點長啊,我是先把bad_key裡面所有的大寫字母都加一遍小寫字母,然後立個flag用來判斷是否有輸出,若for迴圈遍歷完還是無輸出就列印一個'_'用來表示空格。如果bad_key裡面有'+'號,則說明上檔鍵是壞的,無法輸出大寫字母,所以當strinput中的字元是大寫且上檔鍵是壞的時,不執行任何操作,直接continue,當strinput中的字元在bad_key中存在時也直接continue,最後輸出能打印出來的字元。

AC程式碼:

 1 bad_key,strinput = input(),input()
 2 for i in bad_key:
 3     if i.isalpha():
 4         bad_key += i.lower()
 5 flag = True
 6 for i in strinput:
 7     if i.isupper() and bad_key.count('+') > 0:
 8         continue
 9     if i in bad_key:
10         continue
11     print(i,end='')
12     flag = False
13 if flag:
14     print('_')

13 .跟奧巴馬一起程式設計(15)

題目描述:

美國總統奧巴馬不僅呼籲所有人都學習程式設計,甚至以身作則編寫程式碼,成為美國曆史上首位編寫計算機程式碼的總統2014年底,為慶祝“電腦科學教育周”正式啟動,奧巴馬編寫了很簡單的計算機程式碼:在螢幕上畫一個正方形。現在你也跟他一起畫吧!

輸入描述:

輸入在一行中給出正方形邊長N(3 <= N <= 20)和組成正方形邊的某種字元C,間隔一個空格。

輸出描述:

輸出由給定字元Ç畫出的正方形。但是注意到行間距比列間距大,所以為了讓結果看上去更像正方形,我們輸出的行數實際上是列數的50%(四捨五入取整)。

輸入例子:

10 a

輸出例子:

aaaaaaaaaa
a        a
a        a
a        a
aaaaaaaaaa

解題思路: 

首先,根據題意可知行數是列數的50%(四捨五入取整),輸入的邊長也就是col列數,然後利用round()函式來四捨五入求row行數,接著利用for迴圈巢狀,在第一行、最後一行輸出字元c,在中間行的第一列和最後一列輸出字元c,其餘位置輸出空格。

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 int main()
 5 {
 6     int col;
 7     char c;
 8     cin >> col >> c;
 9     int row = round(col/2.0);   //通過round來實現四捨五入
10     for(int i=0;i<row;i++)
11     {
12         for (int j=0;j<col;j++)
13         {
14             if(i==0||j==0||i==row-1||j==col-1)  //只在正方形的邊長部分輸出字元c
15             {
16                 cout << c;
17             }
18             else cout << " ";   //其餘部分全是空格
19         }
20         cout << endl;
21     }
22     return 0;
23 }

14.月餅 (25)

題目描述:

月餅是中國人在中秋佳節時吃的一種傳統食品,不同地區有許多不同風味的月餅。現給定所有種類月餅的庫存量、總售價、以及市場的最大需求量,請你計算可以獲得的最大收益是多少。

注意:銷售時允許取出一部分庫存。樣例給出的情形是這樣的:假如我們有3種月餅,其庫存量分別為18、15、10萬噸,總售價分別為75、72、45億元。如果市場的最大需求量只有20萬噸,那麼我們最大收益策略應該是賣出全部15萬噸第2種月餅、以及5萬噸第3種月餅,獲得72 + 45/2 = 94.5(億元)。

輸入描述:

每個輸入包含1個測試用例。每個測試用例先給出一個不超過1000的正整數N表示月餅的種類數、以及不超過500(以萬噸為單位)的正整數D表示市場最大需求量。隨後一行給出N個正數表示每種月餅的庫存量(以萬噸為單位);最後一行給出N個正數表示每種月餅的總售價(以億元為單位)。數字間以空格分隔。

輸出描述:

對每組測試用例,在一行中輸出最大收益,以億元為單位並精確到小數點後2位。

輸入例子:

3 20
18 15 10
75 72 45

輸出例子:

94.50

解題思路: 

 

首先,通過題意可知月餅有3個變數:庫存量,總售價,單價。所以,先建一個含有這3個變數的moonCake結構體,然後依次輸入月餅的種類數、需求量,每種月餅的庫存量和總售價。在算出月餅的單價之後,根據單價從高到低用sort來對月餅進行排序。最後通過需求量和月餅的庫存量大小的比較來求利潤。

 

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 struct moonCake
 5 {
 6     int amount;     //月餅的庫存量
 7     int totalPrice;  //月餅的總售價
 8     double unitPrice;   //月餅的單價
 9 };
10  
11 bool cmp(moonCake &m1,moonCake &m2)  //按月餅的單價對月餅進行排序
12 {
13     return m1.unitPrice > m2.unitPrice;
14 }
15  
16 int main()
17 {
18     int N, D;  //N為月餅的種類數,D為市場最大需求量
19     cin >> N >> D;
20     moonCake m[N];
21     for (int i = 0; i < N; i++)
22     {
23         cin >> m[i].amount;
24     }
25     for (int i = 0; i < N; i++)
26     {
27         cin >> m[i].totalPrice;
28         m[i].unitPrice = double(m[i].totalPrice)/m[i].amount;
29     }
30     sort(m,m+N,cmp);   
31     double profit = 0;    //總利潤
32     int i = 0;
33     while(D>0)
34     {
35         if(D >= m[i].amount)  
36         {
37             D -= m[i].amount;
38             profit += m[i].totalPrice;
39         }
40         else
41         {
42             profit += m[i].unitPrice*D;
43             break;
44         }
45         i++;
46     }
47     printf("%.2f\n", profit);
48     return 0;
49 }

15. 有幾個PAT(25)

題目描述:

字串APPAPT中包含了兩個單詞“PAT”,其中第一個PAT是第2位(P),第4位(A),第6位(T);第二個PAT是第3位(P),第4位(A),第6位(T)。現給定字串,問一共可以形成多少個PAT?

輸入描述:

輸入只有一行,包含一個字串,長度不超過105,只包含P,A,T三種字母。

輸出描述:

在一行中輸出給定字串中包含多少個PAT。由於結果可能比較大,只輸出對1000000007取餘數的結果。

輸入例子:

APPAPT

輸出例子:

2

解題思路: 

首先,這個題看完之後有點懵逼,然後仔細分析得出這三點:①每個甲對應的PA組合數量是甲之前P的數量;②每個Ť對應的PAT組合數量是Ť之前所有甲對應的PA組合數量的累加;③所有的PAT組合數量是所有Ť對應的PAT組合數量的累加。

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 int main()
 5 {
 6     string s;
 7     cin >> s;
 8     int len = s.length();
 9     int result = 0, countp = 0, countpa = 0, countpat = 0;