写在最前:
PAT乙级的题目算是比较基础的题目,如果说要认认真真的做解析,我觉得有些点也没必要多讲。基础题更加应该看重的是多种方法解一道题。PAT乙级的一些题目,对于数据结构初学者来说也是不错的练手资源。
这个系列会把TZOJ上收录的真题都放上注释和参考代码,每次十题,题目顺序不分先后。
一.害死人不偿命的(3n+1)猜想
描述
卡拉兹(Callatz)猜想:
对任何一个自然数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复砍下去,最后一定在某一步得到n=1。卡拉兹在1950年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证(3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过1000的正整数n,简单地数一下,需要多少步(砍几下)才能得到n=1?
输入
每个测试输入包含1个测试用例,即给出自然数n的值
输出
输出从n计算到1需要的步数。
样例输入
3
样例输出
5
思路:简单的选择结构题目。题目读懂了就行。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int count=0,n;
cin>>n;
while(n!=1){
if(n%2==0){
n=n/2;
count++;
}
else
{
n=(3*n+1)/2;
count++;
}
}
cout<<count<<endl;
return 0;
}
二.跟奥巴马一起编程
描述
美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统。2014年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!
输入
输入在一行中给出正方形边长N(3<=N<=20)和组成正方形边的某种字符C,间隔一个空格。
输出
输出由给定字符C画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的50%(四舍五入取整)。
样例输入
10 a
样例输出
aaaaaaaaaa
a a
a a
a a
aaaaaaaaaa
思路:一道简单的打印题
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i,k;
double n,j;
char c;
cin>>n>>c;
j=(int)((n/2)+0.5);
for(i=1;i<=j;i++)
{
if(i==1||i==j)
{
for(k=0;k<n;k++){
if(k==n-1)
cout<<c<<endl;
else
cout<<c;
}
}
else{
cout<<c;
for(k=1;k<n-1;k++)
cout<<" ";
cout<<c<<endl;
}
}
return 0;
}
三.划拳
描述
划拳是古老中国酒文化的一个有趣的组成部分。酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。
下面给出甲、乙两人的划拳记录,请你统计他们最后分别喝了多少杯酒。
输入
输入第一行先给出一个正整数N(<=100),随后N行,每行给出一轮划拳的记录,格式为:
甲喊 甲划 乙喊 乙划
其中“喊”是喊出的数字,“划”是划出的数字,均为不超过100的正整数(两只手一起划)。
输出
在一行中先后输出甲、乙两人喝酒的杯数,其间以一个空格分隔。
样例输入
5
8 10 9 12
5 10 5 10
3 8 5 12
12 18 1 13
4 16 12 15
样例输出
1 2
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,i,j,k,a,b,c,d,s1=0,s2=0;
cin>>n;
while(n--)
{
cin>>a>>b>>c>>d;
if(b==a+c&&d!=a+c)
s2++;
else if(d==a+c&&b!=a+c)
s1++;
a=0;
b=0;
c=0;
d=0;
}
cout<<s1<<" "<<s2<<endl;
return 0;
}
四.换个格式输出整数
描述
让我们用字母B来表示“百”、字母S表示“十”,用“12...n”来表示个位数字n(<10),换个格式来输出任一个不超过3位的正整数。例如234应该被输出为BBSSS1234,因为它有2个“百”、3个“十”、以及个位的4。
输入
每个测试输入包含1个测试用例,给出正整数n(<1000)。
输出
每个测试用例的输出占一行,用规定的格式输出n。
样例输入
234
样例输出
BBSSS1234
提示
输入样例2:
23
输出样例2:
SS123
#include<bits/stdc++.h>
using namespace std;
int main()
{
int bai=0,shi=0,ge,num;
cin>>num;
bai=num/100;
shi=num/10-10*bai;
ge=num%10;
for(int i=0;i<bai;++i)
cout<<'B';
for(int i=0;i<shi;++i)
cout<<'S';
for(int i=0;i<ge;++i)
cout<<i+1;
return 0;
}
五.说反话
描述
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入
测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有多余的空格。
输出
输出只有一行,输出倒序后的句子,各个单词之间一个空格隔开。
样例输入
Hello World Here I Come
样例输出
Come I Here World Hello
#include<bits/stdc++.h>
using namespace std;
stack<string>ss;
char ch;
char c[1001];
string s;
int main()
{
cin>>s;
ss.push(s);
while((ch=getchar()!='\n')){
cin>>s;
ss.push(s);
}
while(!ss.empty()){
cout<<ss.top();
ss.pop();
if(ss.size()!=0)
{
cout<<" ";
}
}
return 0;
}
六.成绩排名
描述
读入n名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。
输入
每个测试输入包含1个测试用例,格式为
第1行:正整数n
第2行:第1个学生的姓名 学号 成绩
第3行:第2个学生的姓名 学号 成绩
... ... ...
第n+1行:第n个学生的姓名 学号 成绩
其中姓名和学号均为不超过10个字符的字符串,成绩为0到100之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
输出
对每个测试用例输出2行,第1行是成绩最高学生的姓名和学号,第2行是成绩最低学生的姓名和学号,字符串间有1空格。
样例输入
3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
样例输出
Mike CS991301
Joe Math990112
#include<bits/stdc++.h>
using namespace std;
typedef struct
{
char name[101];
char number[101];
int grade;
}student;
int main()
{
int n;
student max,min,stu;
cin>>n;
int x=0,y=100;
for(int i=0;i<n;i++)
{
scanf("%s%s%d",stu.name,stu.number,&stu.grade);
if(x<=stu.grade)
{
x=stu.grade;
max=stu;
}
if(y>=stu.grade)
{
y=stu.grade;
min=stu;
}
}
printf("%s %s\n%s %s",max.name,max.number,min.name,min.number);
return 0;
}
七.写出这个数
描述
读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字。
输入
每个测试输入包含1个测试用例,即给出自然数n的值。这里保证n小于10100。
输出
在一行内输出n的各位数字之和的每一位,拼音数字间有1 空格,但一行中最后一个拼音数字后没有空格。
样例输入
1234567890987654321123456789
样例输出
yi san wu
#include<stdio.h>
#include<string.h>
int main()
{
int i,k=0,sum=0;
char n[101];
scanf("%s",n);
int len=strlen(n);
for(i=0;i<len;i++)
sum+=n[i]-'0';
int num[5];
if(sum==0)
num[k++]=0;
else
{
while(sum)
{
num[k++]=sum%10;
sum=sum/10;
}
}
for(i=k-1;i>=0;i--)
{
switch(num[i])
{
case 0:printf("ling");break;
case 1:printf("yi");break;
case 2:printf("er");break;
case 3:printf("san");break;
case 4:printf("si");break;
case 5:printf("wu");break;
case 6:printf("liu");break;
case 7:printf("qi");break;
case 8:printf("ba");break;
case 9:printf("jiu");break;
default:break;
}
if(i)
printf(" ");
}
printf("\n");
return 0;
}
八.在霍格沃滋找零钱
描述
如果你是哈利●波特迷,你会知道魔法世界有它自己的货币系统 ―― 就如海格告诉哈利的:“十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特(Knut)兑一个西可,很容易。”现在,给定哈利应付的价钱P和他实付的钱A,你的任务是写一个程序来计算他应该被找的零钱。
输入
输入在1行中分别给出P和A,格式为“Galleon.Sickle.Knut”,其间用1个空格分隔。这里Galleon是[0, 107]区间内的整数,Sickle是[0, 17)区间内的整数,Knut是[0, 29)区间内的整数。
输出
在一行中用与输入同样的格式输出哈利应该被找的零钱。如果他没带够钱,那么输出的应该是负数。
样例输入
10.16.27 14.1.28
样例输出
3.2.1
提示
输入样例2:
14.1.28 10.16.27
输出样例2:
-3.2.1
思路:和零钱换算类差不多思路,就是把每种货币统一换成最小的货币,然后就简单了。
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long int s1,g1,k1;//29个k换一个s,17个s换一个g,g>s>k
long long int s2,g2,k2;
long long int sum=0,d;
char n;
cin>>g1>>n>>s1>>n>>k1>>g2>>n>>s2>>n>>k2;
s2-=s1;
g2-=g1;
k2-=k1;
sum+=g2*29*17+s2*29+k2;
if(sum<0)
cout<<'-';
k2=sum%29;
sum/=29;
s2=sum%17;
g2=sum/17;
cout<<abs(g2)<<'.'<<abs(s2)<<'.'<<abs(k2);
return 0;
}
九.打印沙漏
描述
本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
*****
***
*
***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入
输入在一行给出1个正整数N(<=1000)和一个符号,中间以空格分隔。
输出
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
样例输入
19 *
样例输出
*****
***
*
***
*****
2
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,x;
char c;
cin>>x>>c;
n=floor(sqrt(double(x+1)/2));
for(int i=0;i<n-1;i++)
{
for(int j=0;j<i;j++)
cout<<' ';
for(int j=0;j<(2*n-1-2*i);j++)
cout<<c;
cout<<endl;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n-i-1;j++)
cout<<' ';
for(int j=0;j<2*i+1;j++)
cout<<c;
cout<<endl;
}
cout<<x-2*n*n+1<<endl;
return 0;
}
十.挖掘机技术哪家强
描述
为了用事实说明挖掘机技术到底哪家强,PAT组织了一场挖掘机技能大赛。现请你根据比赛结果统计出技术最强的那个学校。
输入
输入在第1行给出不超过105的正整数N,即参赛人数。随后N行,每行给出一位参赛者的信息和成绩,包括其所代表的学校的编号(从1开始连续编号)、及其比赛成绩(百分制),中间以空格分隔。
输出
在一行中给出总得分最高的学校的编号、及其总分,中间以空格分隔。题目保证答案唯一,没有并列。
样例输入
6
3 65
2 80
1 100
2 70
3 40
3 0
样例输出
2 150
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[100001];
memset(a,0,sizeof(a));
int n,x,y;
int max=0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>x>>y;
a[x]+=y;
if(a[x]>a[max])
max=x;
}
cout<<max<<" "<<a[max];
return 0;
}
未完待续
欢迎私信、评论区交流!