PAT乙级(Basic Level)真题训练

Posted m17773572025

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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如果C等于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与stdin的同步压压惊,真的怕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)

题目描述:

要获得一个C语言程序的运行时间,常用的方法是调用头文件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
",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
", 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;
10     for (auto i:s)
11     {
12         if(i == P)
13         {
14             countp++;
15         }
16         else if(i == A)
17         {
18             countpa += countp;
19         }
20         else if(i == T)
21         {
22             countpat += countpa;
23             countpat %= 1000000007;
24         }
25     }
26     cout << countpat<< endl;
27     return 0;
28 }

未完待续······

 

以上是关于PAT乙级(Basic Level)真题训练的主要内容,如果未能解决你的问题,请参考以下文章

JAVA1003 我要通过!(20分) PAT乙级 PAT (Basic Level)Practice (中文)

JAVA1004 成绩排名 (20分) PAT乙级 PAT (Basic Level) Practice(中文)

JAVA1003 我要通过!(20分) PAT乙级 PAT (Basic Level)Practice (中文)

JAVA1007 素数对猜想 (20分) PAT乙级 PAT (Basic Level) Practice (中文)

JAVA1006 换个格式输出整数 (15分) PAT乙级 PAT (Basic Level) Practice (中文)

JAVA1008 数组元素循环右移问题 (20分) PAT乙级 PAT (Basic Level) Practice (中文)