[算法笔记-最全的PAT解答]PAT乙级1011-1015题解

这个专栏的每篇博客旨在分享刷题的心路历程,题解所思都是自己所想,有不对的地方欢迎指正

1011 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

要点:本题需要注意的就是int , long , long long 型数据的大小,本题中2个[-2^31,2 ^31-1]的数相加的和,如果用int型数据存储,是会导致溢出而不能AC的;此外,每行输出Case #X:true/false,即根据Case %d : true/false来得出结果,%d->x应该用一个变量,我这里用的是cnt,初始值为1,每次输出的时候都是cnt++,cnt是count的缩写,常用来记录编号和个数。不过我有一点没想通,如果我定义int a , b ,long c,按道理来说不应该是也能过测试点吗。。不知道为啥过不了5555qwq
代码:

#include<cstdio>
int main(){
	int t , cnt = 1;
	scanf("%d",&t);
	while(t--){
		long  a , b , c;
		scanf("%ld%ld%ld",&a,&b,&c);
		if(a+b>c){
			printf("Case #%d: true\n",cnt++);
		}
		else{
			printf("Case #%d: false\n",cnt++);
		}
	}
	return 0;
}

1012 数字分类

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

A​1= 能被 5 整除的数字中所有偶数的和;
A​2= 将被 5 除后余 1 的数字按给出顺序进行交错求和,即计算 n​1−n2+n3−n4⋯;
A​3 = 被 5 除后余 2 的数字的个数;
A4 = 被 5 除后余 3 的数字的平均数,精确到小数点后 1 位;A5= 被 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

要点:根据题目要求显然要先定义一个ans[5]数组来存放每种情况的答案;此外,因为如果某一类数字不存在的情况下要在相应位置输出N,因而需要另外定义一个cnt[5]数组,cnt[i] == 0的时候则输出N,否则输出该类数字的答案;需要注意的是A4的值,输出的时候应该是(double)ans[4]/cnt[4],即先把ans[4]从int型转换为double型,再/ans[4];如果写成(double)(ans[4]/cnt[4])则会输出9.0(按输出样例1),29/3 = 9->(double)9->9.0
代码:

#include<cstdio>
int main(){
	int n , temp;
	int cnt[5] = {0};
	int ans[5] = {0};
	scanf("%d",&n);
	for(int i = 0;i<n;i++){
		scanf("%d",&temp);
		if(temp%10==0){
			ans[0] += temp;
			cnt[0]++;
		}
		else if(temp%5==1){
			if(cnt[1]%2==0){
				ans[1] += temp;
			}
			else{
				ans[1] -= temp;
 			}
 			cnt[1]++;
		}
		else if(temp%5==2){
			cnt[2]++;
		}
		else if(temp%5==3){
			ans[3] += temp;
			cnt[3]++;
		}
		else if(temp%5==4){
			if(temp>ans[4]){
				ans[4] = temp;
			}
			cnt[4]++;
		}
	}
	if(cnt[0]==0){
		printf("N ");
	}else{
		printf("%d ",ans[0]);
	}
	if(cnt[1]==0){
		printf("N ");
	}else{
		printf("%d ",ans[1]);
	}
	if(cnt[2]==0){
		printf("N ");
	}else{
		printf("%d ",cnt[2]);
	}
	if(cnt[3]==0){
		printf("N ");
	}else{
		printf("%.1f ",(double)ans[3]/cnt[3]);
	}
	if(cnt[4]==0){
		printf("N");
	}else{
		printf("%d",ans[4]);
	}
	return 0;
} 

1013 数素数

令 P​i 表示第 i 个素数。现任给两个正整数 M≤N≤10^​4,请输出 PM到 PN的所有素数。

输入格式:
输入在一行中给出 M 和 N,其间以空格分隔。

输出格式:
输出从 P​M 到 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

要点:又是素数问题,既然要输出从第M个到第N个的所有素数,那么不妨定义一个prime[maxn] (maxn=10010)的数组,存放从第一个到第N个的所有素数,然后输出的时候输出从第M个素数到第N个素数,另外既然要每10个换行,那就统计cnt根据题意来换行
代码:

#include<cstdio>
#include<cmath>
const int MAX = 1000001;
const int maxn = 10010;
int cnt = 0;
bool isPrime(int n){
	if(n<=1)return false;
	int sqr = (int)sqrt(1.0*n);
	for(int i = 2;i <= sqr;i++){
		if(n%i==0)return false;
	}
	return true;
}
int prime[maxn] , num = 1;
//用空间换时间 就是用一个prime[maxn]数组提前把这些素数计算出来存放起来
//也就是打表 
void Find_Prime(int n){
	for(int i = 2;i<=MAX;i++){
		if(isPrime(i)){
			prime[num++] = i;
			if(num>n)break;
		}
	}
}
int main(){
	int m , n;
	scanf("%d%d",&m,&n);
	Find_Prime(n);
	for(int i = m;i<=n;i++){
		printf("%d",prime[i]);
		cnt++;
		if(cnt%10!=0 && i<n)printf(" ");
		else printf("\n");//每10个数字要换行 
	}
	return 0;	
}

1014 福尔摩斯的约会

大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm。大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间星期四 14:04,因为前面两字符串中第 1 对相同的大写英文字母(大小写有区分)是第 4 个字母 D,代表星期四;第 2 对相同的字符是 E ,那是第 5 个英文字母,代表一天里的第 14 个钟头(于是一天的 0 点到 23 点由数字 0 到 9、以及大写字母 A 到 N 表示);后面两字符串第 1 对相同的英文字母 s 出现在第 4 个位置(从 0 开始计数)上,代表第 4 分钟。现给定两对字符串,请帮助福尔摩斯解码得到约会的时间。

输入格式:
输入在 4 行中分别给出 4 个非空、不包含空格、且长度不超过 60 的字符串。

输出格式:
在一行中输出约会的时间,格式为 DAY HH:MM,其中 DAY 是某星期的 3 字符缩写,即 MON 表示星期一,TUE 表示星期二,WED 表示星期三,THU 表示星期四,FRI 表示星期五,SAT 表示星期六,SUN 表示星期日。题目输入保证每个测试存在唯一解。

输入样例:
3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm

输出样例:
THU 14:04

要点:总共前面两个字符串中需要得到两对相同的字符,后面两个字符串中需要得到第一对相同的字符的位置。且之后都有对应输出,那么就此建立一个same_char[2]的数组,依次存放前面两个字符串中相同的字符。比如第一个要输出“DAY”,比如"MON",“TUE”,…所以应该是cout<<week[same_char[0]-‘A’]];第二个字符对应钟头,需要分两种情况得到对应的,一种如果是数字,一种如果不是数字,分别处理就好
代码:

#include<iostream>
#include<cctype>
using namespace std;
int main(){
	string a , b , c , d;
	cin>>a>>b>>c>>d;
	char same_char[2];
	int pos , i = 0 , j = 0;
	//前面两个字符串中第一对相同的字符 
	while(i<a.length()&&i<b.length()){
		if(a[i]==b[i]&&a[i]>='A'&&a[i]<='G'){
			same_char[0] = a[i];
			break;
		}
		i++;//即此对应的字符没找到 那么就往下找 
	}
	i = i + 1;
	//前面两个字符串中第二对相同的字符 
	while(i<a.length()&&i<b.length()){
		if(a[i]==b[i]&&((a[i]>='A'&&a[i]<='N')||isdigit(a[i]))){
			same_char[1] = a[i];
			break;
		}
		i++;
	} 
	//后面两个字符串中第一对相同字符的位置 
	while(j<c.length()&&j<d.length()){
		if(c[j]==d[j]&&isalpha(c[j])){
			pos = j;
			break; 
		}
		j++;
	}
	string week[7] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};
	int m = isdigit(same_char[1])?same_char[1]-'0':same_char[1]-'A'+10;
	cout<<week[same_char[0]-'A']<<" ";
	printf("%02d:%02d",m,pos);
	return 0;
} 

1015 德才论

宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”

现给出一批考生的德才分数,请根据司马光的理论给出录取排名。

输入格式:
输入第一行给出 3 个正整数,分别为:N(≤10^5),即考生总数;L(≥60),为录取最低分数线,即德分和才分均不低于 L 的考生才有资格被考虑录取;H(<100),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于 H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线 L 的考生也按总分排序,但排在第三类考生之后。

随后 N 行,每行给出一位考生的信息,包括:准考证号 德分 才分,其中准考证号为 8 位整数,德才分为区间 [0, 100] 内的整数。数字间以空格分隔。

输出格式:
输出第一行首先给出达到最低分数线的考生人数 M,随后 M 行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。

要点:每个考生都有三个属性id,de,cai,首先根据输出格式中的排序规则编写bool cmp(node a,node b){};然后根据德才的分数所属范围分别归属到对应的类别中:“才德全尽者”,“德胜才者”,“才德兼亡但尚有才者”,“其他情况”,也就是if-else if-else的运用;此外,归属类别用vector v[4]进行push_back
代码:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct node{
	int id , de , cai;
};
//排序规则 
//按德才总分从高到低排序 
//当某类考生中有多人总分相同时 按其得分降序输出 
//若得分也并列 则按准考证号的升序输出 
int cmp(node a , node b){
	if((a.de + a.cai) != (b.de + b.cai)){
		return (a.de+a.cai)>(b.de+b.cai);
	}
	else if(a.de != b.de){
		return a.de > b.de;
	}
	else{
		return a.id <= b.id;
	}	
} 

int main(){
	int n , l , h;
	scanf("%d %d %d", &n , &l , &h);
	vector<node> v[4];
	node tmp;
	int total = n;
	for(int i = 0;i<n;i++){
		scanf("%d %d %d",&tmp.id,&tmp.de,&tmp.cai);
		if(tmp.de<l||tmp.cai<l)total--;
		else if(tmp.de>=h&&tmp.cai>=h)v[0].push_back(tmp);
		else if(tmp.de>=h&&tmp.cai<h)v[1].push_back(tmp);
		else if(tmp.de<h&&tmp.cai<h&&tmp.de>=tmp.cai)v[2].push_back(tmp);
		else v[3].push_back(tmp);
	}
	printf("%d\n",total);
	for(int i = 0;i<4;i++){
		sort(v[i].begin(),v[i].end(),cmp);
		for(int j = 0;j<v[i].size();j++){
			printf("%d %d %d\n",v[i][j].id,v[i][j].de,v[i][j].cai);
		}
	}
	return 0;
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值