刷题日志1.0

@Welcome To Quinn’s Energy Station

本日志习题均来自codeup.cn及patest.cn

2021年01月10日 ⛅

一、简单模拟

PAT B1011.A+B和C

题目描述:
给定区间 [−2​31,2​31] 内的 3 个整数 A、B 和 C,请判断 A+B 是否大于 C。
输入格式:
输入第 1 行给出正整数 T (≤10),是测试用例的个数。随后给出 T 组测试用例,每组占一行,顺序给出 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

思路:
输入T(组数),step表示当前是第几组数据,初值为1。对于每组数据,判断A+B是否大于C。题目怎么说就怎么写!
【Notes】
1、程序实现执行n次循环,除了for之外,更简单的写法是while(n–)。注意!如果写成while(–n)就是循环n-1次,而不是n次。
2、题目给出T的范围超出了int型的范围([-263,263-1])啊啊啊啊烦死了要 次方为什么打不出来!另外,两个int型的变量相加,结果是可能超过int型的。所以要A、B、C定义为 long long 型,输入输出格式是%lld。
【Worning】
这块我提交了好几次都是格式错误,最后发现题目中的输出用例冒号后是有空格的,所以之后大家把题目中的case语句直接粘到代码中去就好啦。

代码示例如下:

#include<stdio.h>
int main(){
	int T,step=1; 
    scanf("%d",&T);  //输入组数
	while(T--){     //循环T次,T组数据
			long long a,b,c;
			scanf("%lld%lld%lld",&a,&b,&c);
			if(a+b>c){
				printf("Case #%d: true\n",step++);
			}else{
				printf("Case #%d: false\n",step++);
			}
		}
	return 0;
}

PAT B1016.部分A+B

题目描述:
在这里插入图片描述
输入格式:
在这里插入图片描述
输出格式:
在这里插入图片描述
输入样例 1:

3862767 6 13530293 3

输出样例 1:

399

输入样例 2:

3862767 1 13530293 8

输出样例 2:

0

思路:
输入A、DA、B、DB,我们可以利用取余枚举A中的每一位,若该位等于DA,则令PA=PA*10+DA,PB逻辑相同。

代码示例如下:

#include<stdio.h>
int main(){
	long long a,b,da,db;
	scanf("%lld%lld%lld%lld",&a,&da,&b,&db);
	long long pa=0,pb=0;
	while(a!=0){
		if(a%10==da) pa=pa*10+da;
		a=a/10;
	}
	while(b!=0){
		if(b%10==db) pb=pb*10+db;
		b=b/10;
	}
	printf("%lld\n",pa+pb);
	return 0;
}

PAT B1026.程序运行时间

题目描述: 要获得一个C语言程序的运行时间,常用的方法是调用头文件 time.h,其中提供了 clock() 函数,可以捕捉从程序开始运行到 clock() 被调用时所耗费的时间。这个时间单位是 clock tick,即“时钟打点”。同时还有一个常数CLK_TCK,给出了机器时钟每秒所走的时钟打点数。于是为了获得一个函数 f 的运行时间,我们只要在调用 f 之前先调用 clock(),获得一个时钟 打点数 C1;在 f 执行完成后再调用 clock(),获得另一个时钟打点数 C2;两次获得的时钟打点数之差 (C2-C1) 就是 f 运行所消耗的时钟打点数,再除以常数 CLK_TCK,就得到了以秒为单位的运行时间。
这里不妨简单假设常数 CLK_TCK 为 100。现给定被测函数前后两次获得的时钟打点数,请你给出被测函数运行的时间。
输入格式:
输入在一行中顺序给出 2 个整数 C1 和 C2。注意两次获得的时钟打点数肯定不相同,即 C1 < C2,并且取值在 [0,107​​]。
输出格式:
在一行中输出被测函数运行的时间。运行时间必须按照 hh:mm:ss(即2位的 时:分:秒)格式输出;不足 1 秒的时间四舍五入到秒。
输入样例:

123 4577973

输出样例:

12:42:59

思路:
累了,按照题目写就行。

代码示例如下:

 #include<stdio.h>
int main(){
    int c1,c2;
	scanf("%d %d",&c1,&c2);
	if(c1<c2){
	  int time=(c2-c1)/100; //运行时间 
	  int hh=time/60/60;    //所用秒数除以3600取整即为时针数 
	  int mm=(time%3600)/60;//分针数 
	  int ss=0;
	  //怎么实现小数除呢???这块代码有问题!(四舍五入) 
	  float a=float(time%3600%60/60); 
	  if (float(a+0.5)>=1){ //不足 1 秒的时间四舍五入到秒 
	  	ss=time%3600%60+1;
	  }
	  else{
	  	ss=time%3600%60;
	  }
	  printf("%d:%d:%d",hh,mm,ss);
	}
	else{
	  printf("输入有误!");
	}
	return 0;	
} 

2021年01月11日 ⛅

PAT B1046.划拳

问题描述:
划拳是古老中国酒文化的一个有趣的组成部分。酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。
下面给出甲、乙两人的划拳记录,请你统计他们最后分别喝了多少杯酒。
输入格式:
输入第一行先给出一个正整数 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

思路:
变量count1,count2分别记录甲、乙输的次数,即喝酒杯数,此题较简单,具体过程见代码。

代码示例如下:

#include<stdio.h>
int main(){
	int J,Ja,Y,Ya;
	int N=0,count1=0,count2=0;//count1为甲输的次数,count2为乙输的次数 
	    scanf("%d",&N); //输入划拳次数 
	    while(N--){
		      scanf("%d%d%d%d",&J,&Ja,&Y,&Ya);
	          if(J+Y==Ya&&J+Y!=Ja){  //甲输 
	             count1++;
              }
	          else if(J+Y==Ja&&J+Y!=Ya){ //乙输 
	              count2++;
              }
         }
	printf("%d %d\n",count1,count2);
	return 0;
}

PAT B1012.数字分类

问题描述:
给定一系列正整数,请按要求对数字进行分类,并输出以下 5 个数字:
A​1 = 能被 5 整除的数字中所有偶数的和;
A​2 = 将被 5 除后余 1 的数字按给出顺序进行交错求和,即计算 n1−n2+n3−n4 ⋯;
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

思路:
使用一个数组记录符合条件的数字是否存在,再用另一个数组记录输出结果。对于读入的数字,进而判断其属于哪类。

代码示例如下:

include<cstdio>
	int count[5]={0};
	int sum[5]={0};
	int n,x;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&x);
		//if(x%5==0&&x%2==0){   //为什么不能这样写??
		if(x%5==0){       //A1类
			if(x%2==0){
			sum[0]+=x;
			count[0]++;
		    }
		}
		else if(x%5==1){   //A2类
			if(count[1]%2==0){
				sum[1]+=x;
			}else{
				sum[1]-=x;
			}
			count[1]++;
		}
		else if(x%5==2){   //A3类
			count[2]++;
		}
		else if(x%5==3){   //A4类
			sum[3]+=x;
			count[3]++;
		}
		else{
			if(x>sum[4]){    //A5类(其余的数即为“被5整除余4”的数)
				sum[4]=x;
			}
			count[4]++;
	    }
	}
	if(count[0]==0) printf("N "); //注意空格
	else printf("%d ",sum[0]);
	if(count[1]==0) printf("N ");
	else printf("%d ",sum[1]);
	if(count[2]==0) printf("N ");
	else printf("%d ",count[2]);
	if(count[3]==0) printf("N ");
	else printf("%.1f ",sum[3]*1.0/count[3]);//(%.1f)小数点后保留一位,前加double或用1.0进行格式转换 
	if(count[4]==0) printf("N");
	else printf("%d",sum[4]);
    return 0;
} 

PAT B1018.锤子剪刀布

问题描述:
大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:
在这里插入图片描述
现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。
输入格式:
输入第 1 行给出正整数 N,即双方交锋的次数。随后 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>
int change(char c){
	if(c=='B') return 0;
	if(c=='C') return 1;
	if(c=='J') return 2;
} 
int main(){
	int n;
	char arr[3]={'B','C','J'};
	scanf("%d",&n);
	int count1[3]={0},count2[3]={0};
	int hand1[3]={0},hand2[3]={0};
	char c1,c2;
	int k1,k2;
	while(n--){
		getchar();
		scanf("%c %c",&c1,&c2);
		k1=change(c1);
		k2=change(c2);
		if((k1+1)%3==k2){
			count1[0]++;
			count2[2]++;
			hand1[k1]++;
		} else if(k1==k2){
			count1[1]++;
			count2[1]++;
		}else{
			count1[2]++;
			count2[0]++;
			hand2[k2]++;
		}
	}
	printf("%d %d %d\n",count1[0],count1[1],count1[2]);
	printf("%d %d %d\n",count2[0],count2[1],count2[2]);
	int id1=0,id2=0;
	for(int i=0;i<3;i++){
		if(hand1[i]>hand1[id1]) id1=i;
		if(hand2[i]>hand2[id2]) id2=i;
	}
	printf("%c %c",arr[id1],arr[id2]);
	return 0;
}

PAT B1021.个位数统计

问题描述:
给定一个k位整数N = dk-110k-1 + … + d1101 + 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

思路:
原本思路是将输入的整数n转化为一维数组,再统计数字出现次数,最后发现十分麻烦。不如直接定义输入端为字符串。

代码示例如下:

#include<stdio.h> 
int main(){
	int a[10]={0};//存放每个数字出现的次数 
	char c[1000];
	scanf("%s",c);	
    for(int i=0;c[i]!='\0';i++){//遍历字符 
		a[c[i]-'0']++;//出现次数 
	}
	for(int i=0;i<10;i++){//升序排列 
		if(a[i]!=0)
			printf("%d:%d\n",i,a[i]);
    }
    return 0;
}

一、入门模拟

1、查找元素

Codeup 1934 .找x

问题描述:输入一个数n,然后输入n个数值各不相同,再输入一个值x,输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1)。

输入:测试数据有多组,输入n(1<=n<=200),接着输入n个数,然后输入x。

输出:对于每组输入,请输出结果。

样例输入:
4
1 2 3 4
3

样例输出:
2

思路:
我们可以设定一个数组arr,用来存放n个数,然后遍历数组,寻找使得arr[k]==x成立的下标k。若找到则输出k,并退出查找;若当k遍历完数组之后还没有找到x,则输出-1。

看到题后第一次写出的代码:

#include<stdio.h>
const int maxn=200; 
int arr[maxn];         //存放n个数 
int main(){	
	int n,x;
		scanf("%d",&n);
	if(n!=0){
		for(int i=0;i<n;i++){	
		scanf("%d",&arr[i]);     //输入	
	    }
	}
	while(n!=0){	
		scanf("%d",&x);	    //输入想要查询的数
		for(int k=0;k<n;k++){	 //遍历数组	
			if(arr[k]==x){		//找到x	
			printf("%d\n",k);	//输出对应下标	
			break;	//退出查询	
		    }	    
		    if(k==n){   	//没有找到
		    	printf("-1\n");   //输出-1 	
			}
		}
	}
	return 0;
}

我的写法好像有点辣鸡?但是按照思路觉得这样很清晰,但是!!此答案在编译器上运行是正常的,而在oj平台上一直显示输出超限,绞尽脑汁百思不得其解,最后只能借助广大网友的智慧脑瓜,问题就是应该把输入写在while里面就解决问题啦!

以下是改正后的代码:

#include<stdio.h>
const int maxn=200;
int arr[maxn];
int main(){	
	int n,x;
    while(scanf("%d",&n)!=EOF){
    	for(int i=0;i<n;i++){
    		scanf("%d",&arr[i]);
		}
		scanf("%d",&x);
		int k;
		for(k=0;k<n;k++){
			if(arr[k]==x){
				printf("%d\n",k);
				break;
			}
		}
		if(k==n){
			printf("-1\n");
		}
	}
	return 0;
}

2、图形输出

PAT B1036(跟奥巴马一起编程)

问题描述:
美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统。2014 年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!

输入格式:
输入在一行中给出正方形边长 N(3≤N≤20)和组成正方形边的某种字符 C,间隔一个空格。

输出格式:
输出由给定字符 C 画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的 50%(四舍五入取整)。

输入样例:
10 a

输出样例:
aaaaaaaaaa
a a
a a
a a
aaaaaaaaaa

思路:行数是列数的50%,且采取四舍五入,则当列数col是偶数时,行数是col/2;当列数col是奇数时,行数是col/2+1。

代码如下:

#include<stdio.h>
int main(){
	int row,col;  //行、列 
	char C;
	scanf("%d %c",&col,&C);  //输入列数(即边长)和字符 
	if(col%2==0)  //col为偶数 
	  row=col/2;
	else        //col为奇数 
	  row=col/2+1;
	//第1行 
	for(int i=0;i<col;i++){
		printf("%c",C); 
	}
	printf("\n"); 
	//第2~row-1行 
	for(int i=2;i<row;i++){
		printf("%c",C);
		for(int j=0;j<col-2;j++){
			printf(" ");	
		}
		printf("%c\n",C);
	} 
	//第row行
	for(int i=0;i<col;i++){
		printf("%c",C);
	} 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值