PAT (Basic Level) Practice (中文)入门篇(1)C

我们两清 提交于 2020-01-19 00:34:32

1001 害死人不偿命的(3n+1)猜想 (15分)C语言

卡拉兹(Callatz)猜想:

对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……

我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?

输入格式:
每个测试输入包含 1 个测试用例,即给出正整数 n 的值。

输出格式:
输出从 n 计算到 1 需要的步数。

输入样例:

3

输出样例:

5

原题链接

思路:
读入题目给出的n,之后用while循环语句反复判段n是否为1

  • 如果n为1,则退出循环;
  • ruguon不为1,则判断n是否为偶数,如果是偶数,则令n除于2;则令n为(3*n+)/2,之后令计数器count加1;
  • 退出循环时,count值即为答案。
#include <stdio.h>
int main(){
	int n,count=0;
	scanf("%d",&n); //输入n 
	while(n!=1){ //循环判断n是否为1 
		if(n%2==0) n=n/2; //如果是偶数 
		else n=(3*n+1)/2; //如果是奇数 
		count++; //计数器加1 
	}
	printf("%d\n",count);
	return 0;
} 

1032 挖掘机技术哪家强 (20分)

为了用事实说明挖掘机技术到底哪家强,PAT 组织了一场挖掘机技能大赛。现请你根据比赛结果统计出技术最强的那个学校。

输入格式:
输入在第 1 行给出不超过 10^​5的正整数 N,即参赛人数。随后 N 行,每行给出一位参赛者的信息和成绩,包括其所代表的学校的编号(从 1 开始连续编号)、及其比赛成绩(百分制),中间以空格分隔。

输出格式:
在一行中给出总得分最高的学校的编号、及其总分,中间以空格分隔。题目保证答案唯一,没有并列。

输入样例:

6
3 65
2 80
1 100
2 70
3 40
3 0

输出样例:

2 150

原题链接
思路:

  • 令数组school[10010]记录每个学校的总分,初始值为0.对每一个读入的学校schID与其对应的分数score,令school[schID]+=score。
  • 令变量k记录最高总分的学校编号,变量MAX记录最高总分,初值为-1。由于学校是连续编号的,因此美剧编号1~N,不断更新k与MAX即可。
#include <stdio.h>
int school[100010]={0}; //记录每个学校的总分 
int main(){
	int n,i,schID,score;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d %d",&schID,&score); //学校ID、分数 
		school[schID] += score; //学习schID的总分增加score 
	} 
	int k=1,MAX= -1; //总得分最高的学校的编号、及其总分 
	for(i=0;i<=n;i++){ //从所有学校中选出总分最高的一个 
		if(school[i]>MAX){
			MAX = school[i];
			k=i;
		}
	} 
	printf("%d %d\n",k,MAX); //输出总得分最高的学校的编号、及其总分 
	return 0;
}

1012 数字分类 (20分)

给定一系列正整数,请按要求对数字进行分类,并输出以下 5 个数字:

  • A1 = 能被 5 整除的数字中所有偶数的和;
  • A​2 = 将被 5 除后余 1 的数字按给出顺序进行交错求和,即计算 n1−n​2+n​3−n​4⋯;
  • A​3 = 被 5 除后余 2 的数字的个数;
  • A​4​​ = 被 5 除后余 3 的数字的平均数,精确到小数点后 1 位;
  • A​5 = 被 5 除后余 4 的数字中最大数字。

输入格式:
每个输入包含 1 个测试用例。每个测试用例先给出一个不超过 1000 的正整数 N,随后给出 N 个不超过 1000 的待分类的正整数。数字间以空格分隔。

输出格式:
对给定的 N 个正整数,按题目要求计算 A​1~A​5并在一行中顺序输出。数字间以空格分隔,但行末不得有多余空格。

若其中某一类数字不存在,则在相应位置输出 N。

输入样例 1:

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

输出样例 1:

30 11 2 9.7 9

输入样例 2:

8 1 2 4 5 6 7 9 16

输出样例 2:

N 11 2 N 9

原题链接
思路:

  • 不难,但很坑。
  • 一开始错了一个用例,看网友分享才发现坑点,
  • a2交错和为0,不代表不存在,故还是要统计a2的数量的。
#include <stdio.h>
int main(){
	int N,i;
	while(scanf("%d",&N)!=EOF){
		int a1=0,a2=0,a21=0,a3=0,a4=0,a41=0,a5=0,num,re = 1;
		for(i=0;i<N;i++){
			scanf("%d",&num);
			if(num%10==0) a1+=num; //能被5整除的数字中所有偶数的和
			if(num%5==1){ //将被5除后余1的数字按给出顺序进行交错求和 
                a21++;
				if(a21%2==1) a2 += num; //奇数个相加 
				else a2 -= num; //偶数个相减 
			}
			if(num%5==2) a3++;
			if(num%5==3){
				a4 += num; //A4求合 
				a41++; //计数 
			}
			if(num%5==4){
				if(num>a5) a5=num;
			}
		}
		if(a1) {printf("%d ",a1);} else {printf("N ");}
    	if(a21) {printf("%d ",a2);} else {printf("N ");} //判断a21,坑点!!
    	if(a3) {printf("%d ",a3);} else {printf("N ");}
    	if(a41) {printf("%.1lf ",(double)a4/a41);} else {printf("N ");}
    	if(a5) {printf("%d\n",a5);} else {printf("N\n");}
	}
	return 0;
}

1016 部分A+B (15分)

正整数 A 的“D​A​(为 1 位整数)部分”定义为由 A 中所有 D​A组成的新整数 P​A。例如:给定 A=3862767,D​A=6,则 A 的“6 部分”P​A是 66,因为 A 中有 2 个 6。

现给定 A、D​A 、B、D​B,请编写程序计算 P​A​​ +P​B​​ 。

输入格式:
输入在一行中依次给出 A、D​A​​ 、B、D​B,中间以空格分隔,其中 0<A,B<10^​10。

输出格式:
在一行中输出 P​A+P​B的值。

输入样例 1:

3862767 6 13530293 3   

输出样例 1:

399

输入样例 2:

3862767 1 13530293 8

输出样例 2:

0

原题链接
思路

  • 将A,B定义为字符串,通过strlen()函数,获取字符串的长度
  • 遍历字符串,找到相同字符,转换为数字,最后求和
#include <stdio.h>
int main(){
	char a[100],b[100];
	int d1,d2,i,p1=0,p2=0;
	scanf("%s %d %s %d",a,&d1,b,&d2); 
	for(i=0;i<strlen(a);i++){
		if(a[i]==d1+'0') 
			p1=p1*10+d1;
	}
	for(i=0;i<strlen(b);i++){
		if(b[i]==d2+'0') 
			p2=p2*10+d2;
	}
	printf("%d\n",p1+p2);
	return 0;
} 

1018 锤子剪刀布 (20分)

大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:
01

现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。

输入格式:
输入第 1 行给出正整数 N(≤10^​5),即双方交锋的次数。随后 N 行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。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

原题链接
思路

  • 这题不难,但在于统计输、平、赢时要细心
#include <stdio.h>
char max(int B,int C,int J){
	if(B>=C && B>=J) return 'B';
	if(C>B && C>=J) return 'C';
	return 'J';
}
int main(){
	int n,i;
	int a=0,b=0,c=0,a1=0,b1=0,c1=0,d=0;
	char T,F;
	scanf("%d",&n); //双方交锋的次数
	for(i=0;i<n;i++){
		scanf(" %c %c",&T,&F); //甲、乙双方同时给出的的手势,请注意每%c之前的空格 
		if(T=='B'&&F=='C')	a++;
        if(T=='C'&&F=='J')	b++;
        if(T=='J'&&F=='B')	c++;
        if(T=='B'&&F=='J')	c1++;
        if(T=='C'&&F=='B')	a1++;
        if(T=='J'&&F=='C')	b1++;
        if(T==F)	d++;
	}
	printf("%d %d %d\n",a+b+c,d,a1+b1+c1); //甲的胜、平、负次数
	printf("%d %d %d\n",a1+b1+c1,d,a+b+c); //乙的胜、平、负次数
	printf("%c %c",max(a,b,c),max(a1,b1,c1)); //甲、乙获胜次数最多的手势 
	return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!