PTA——520 钻石争霸赛 2021(部分题解)

PTA——520 钻石争霸赛 2021

链接:https://pintia.cn/problem-sets/1392022091148099584/problems/1392808507516067847

7-1 自动编程 (5 分)

输出语句是每个程序员首先要掌握的语句。Python 的输出语句很简单,只要写一个 print(X) 即可,其中 X 是需要输出的内容。

本题就请你写一个自动编程机,对任何一个要输出的整数 N,给出输出这个整数的 Python 语句。

输入格式:

输入给出一个不超过 10^​5的正整数。

输出格式:

在一行中打印输出这个整数的 Python 语句,其中不包含任何空格。

输入样例:

520

输出样例:

print(520)

正确代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int x;
	cin>>x;
	cout<<"print("<<x<<")"<<endl;
	return 0;
} 

7-2 加油冲鸭 (10 分)

宝宝参加运动会的 N 米跑比赛。宝宝每秒钟跑 M 米,跑了 S 秒后,还剩多少米?如果剩下的距离比 N 的一半还远,你就对宝宝喊:“加油鸭!”如果剩下的距离不超过 N 的一半了,就喊:“冲鸭!”

在这里插入图片描述

输入格式:

输入在一行中给出 3 个正整数,分别是 N(不超过 1000),是比赛的总长度;M(不超过 10),是宝宝每秒跑的距离;S(不超过 100),是宝宝跑的秒数。

题目保证宝宝跑完的距离小于 N。

输出格式:

在一行中输出“还剩X米!加油鸭!”或者是“还剩X米!冲鸭!”,其中 X 是宝宝剩下的距离。当然输出的是汉语拼音,即:hai sheng X mi! jia you ya! 或者 hai sheng X mi! chong ya!。

输入样例 1:

100 5 9

输出样例 1:

hai sheng 55 mi! jia you ya!

输入样例 2:

200 6 20

输出样例 2:

hai sheng 80 mi! chong ya!

正确代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,m,s;
	cin>>n>>m>>s;
	int k=n-(m*s);
	if(k>n/2)
		cout<<"hai sheng "<<k<<" mi! jia you ya!"<<endl;
	else cout<<"hai sheng "<<k<<" mi! chong ya!"<<endl;
	return 0;
} 

7-3 520的表白 (10 分)

在这里插入图片描述

“520”是信息时代的爱情节日,谐音“吾爱您”。既然是网络情人节,表白用的定情物也就是通过网络传输的,比如 520 朵玫瑰、520 颗巧克力、520 句“我爱拼题A”……

本题就请你做一个定制化的 520 表白程序,将客户想要表白的句子输出 520 遍。

输入格式:

输入在一行中给出客户想要定制的表白句,是由不超过 9 个数字组成的火星文。

输出格式:

将客户的表白输出 520 遍,每遍占一行。

输入样例:

5201314

输出样例(… 表示省略中间 517 遍):

5201314
5201314

5201314

正确代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	string s;
	cin>>s;
	for(int i=0;i<520;i++) cout<<s<<endl;
	return 0;
} 

7-4 奇葩楼层 (15 分)

几乎每个国家都有自己忌讳的数字,有的大楼在给楼层编号的时候,会刻意跳过含有不吉利数字的编号。比如中国人比较忌讳 4,有的大楼就没有第 4 层、第 14 层 等等,这样楼层的编号就会是 1、2、3、5、…… 即编号为 5 的楼层实际是第 4 层。那么在去掉了忌讳数字之后最高楼层编号为 n 的大楼,实际上有多少层呢?

输入格式:

输入在一行中给出 2 个整数,依次为大楼最高层的编号 n(1<n≤1000),和某国人民忌讳的数字 d(0≤d≤9)。题目保证 n 中不包含 d。注意楼层编号从 1 开始。

输出格式:

在一行中输出该大楼的实际楼层数。

输入样例:

50 4

输出样例:

36

正确代码:

#include<bits/stdc++.h>
using namespace std;
int n,d;
int check(int k){
	while(k){
		int m=k%10;
		k=k/10;
		if(m==d){
			return 1;
		}
	}
	return 0;
}
int main(){
	cin>>n>>d;
	int p=n;
	for(int i=1;i<=n;i++){
		if(check(i)){
			p--;
		}
	}
	cout<<p<<endl;
	return 0;
} 

7-5 大勾股定理 (15 分)

大勾股定理是勾股定理的推广:对任何正整数 n 存在 2n+1 个连续正整数,满足前 n+1 个数的平方和等于后 n 个数的平方和。例如对于 n=1 有 3^ ​2​​ +4 ^​2​​ =5 ^​2​​ ;n=2 有 10 ^​ 2+11 ^ ​2​​ +12 ^ ​2​​ =13 ^ ​2 +14 ^ ​2等。给定 n,本题就请你找出对应的解。

输入格式:

输入在一行中给出正整数 n(≤10^4)。

输出格式:

分两行输出满足大勾股定理的解,格式如下:

a[0]^2 + a[1]^2 + … + a[n]^2 =
a[n+1]^2 + … + a[2n]^2
其中解的数列 a[0] … a[2n] 按递增序输出。注意行首尾不得有多余空格。

输入样例:

3

输出样例:

21^2 + 22^2 + 23^2 + 24^2 =
25^2 + 26^2 + 27^2

思路:暴力,被扣了一分。

代码(部分正确):

#include<bits/stdc++.h>
using namespace std;
int main(){
	long long  n;
	cin>>n;
	//cout<<p1<<" "<<p2<<endl;
	long long a=0,b=0;
	for(int i=1;i<=n+1;i++){
		a+=(i*i);
	}
	for(int i=n+2;i<=2*n+1;i++){
		b+=(i*i);
	}
	int x1,x2,x3,x4;
	x1=1;
	x2=n+1;
	x3=n+2;
	x4 = 2*n+1;
	while(1){
		//cout<<x1<<" "<<x2<<" "<<x3<<" "<<x4<<":"<<a<<" "<<b<<endl;
		if(a==b){
			break;
		}
		else{
			a-=(x1*x1);
			x1++;
			x2++;
			a+=(x2*x2);
			b-=(x3*x3);
			x3++;
			x4++;
			b+=(x4*x4);
		}
	}
	for(int i=x1;i<=x4;i++){
		if(i>x1 && i<=x2){
			cout<<" + ";
		}
		else if(i>x3 && i<=x4){
			cout<<" + ";
		}
		if(i==x3){
			cout<<" ="<<endl;
		}
		cout<<i<<"^2";
		
	}
	cout<<endl;
	return 0;
} 

正确代码:

在这里插入代码片

7-6 矩阵列平移 (20 分)

给定一个 n×n 的整数矩阵。对任一给定的正整数 k<n,我们将矩阵的偶数列的元素整体向下依次平移 1、……、k、1、……、k、…… 个位置,平移空出的位置用整数 x 补。你需要计算出结果矩阵的每一行元素的和。

输入格式:

输入第一行给出 3 个正整数:n(<100)、k(<n)、x(<100),分别如题面所述。

接下来 n 行,每行给出 n 个不超过 100 的正整数,为矩阵元素的值。数字间以空格分隔。

输出格式:

在一行中输出平移后第 1 到 n 行元素的和。数字间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

7 2 99
11 87 23 67 20 75 89
37 94 27 91 63 50 11
44 38 50 26 40 26 24
73 85 63 28 62 18 68
15 83 27 97 88 25 43
23 78 98 20 30 81 99
77 36 48 59 25 34 22

输出样例:

440 399 369 421 302 386 428

样例解读

需要平移的是第 2、4、6 列。给定 k=2,应该将这三列顺次整体向下平移 1、2、1 位(如果有更多列,就应该按照 1、2、1、2 …… 这个规律顺次向下平移),顶端的空位用 99 来填充。平移后的矩阵变成:
11 99 23 99 20 99 89
37 87 27 99 63 75 11
44 94 50 67 40 50 24
73 38 63 91 62 26 68
15 85 27 26 88 18 43
23 83 98 28 30 25 99
77 78 48 97 25 81 22

正确代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,k,x;
	cin>>n>>k>>x;
	int s[n+4][n+4];
	int s2[n+4][n+4];
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>s[i][j];
			s2[i][j]=s[i][j];
		}
	}
	int id=1;
	for(int i=2;i<=n;i=i+2){
		if(id>k){
			id=1;
		}
		for(int j=1;j<=n;j++){
			if(j<=id){
				s2[j][i]=x;
				
			}
			else{
				s2[j][i]=s[j-id][i];
			}
		}
		id++;
	}
	int sum=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			sum+=s2[i][j];
		}
		if(i!=1) cout<<" ";
		cout<<sum;
		sum=0;
	}
	cout<<endl;
	return 0;
} 

7-7 约会大作战 (20 分)

某社团开展了一个“快闪”相亲活动,活动规则如下:

社团负责人将所有人分为两组,并收集了每个人对另外一组的所有人的好感度;
然后社团负责人会随机地在两组各抽取一个人,询问他们是否愿意一起去约会;
所有人对一开始的两次询问一定会拒绝;
从第三次询问开始,如果询问的人的好感度大于这个人之前的两个没能牵手的人,则接受,否则拒绝;
只有两个人同时接受,约会才成立。
约会成立后,后面的询问一律拒绝。
现在给出好感度和每次询问的两个人,请你帮忙计算一下最终有哪些人可以去约会了。

输入格式:

输入第一行是三个数字 N,M,Q (1 ≤ N,M ≤ 100, 1 ≤ Q ≤ 500), 表示分成的两组里,第一组有 N 个人,第二组有 M 个人,共有 Q 次询问。

接下来 N 行,每行 M 个数,第 i 行的第 j 个数表示第一组的第 i 个人对第二组的第 j 个人的好感度数值。数字的绝对值不超过 100。

再接下来的 M 行,每行 N 个数,第 i 行的第 j 个数表示第二组的第 i 个人对第一组的第 j 个人的好感度数值。数字的绝对值同样不超过 100。

最后有 Q 行,每行两个数字 x,y,表示主持人询问第一组的第 x 个人和第 y 个人去不去约会。

每一组内人的编号从 1 开始。

注意: 如果同一对人被询问两次,会被当成两对人处理。

输出格式:

输出若干行,每行两个数 a,b,表示第一组的第 a 个人和第二组的第 b 个人约会成功。顺序按照询问顺序的先后。如果没有一对能约会成功,则输出一行 PTA is my only love。

输入样例:

3 4 12
8 9 1 2
3 4 8 5
1 8 2 9
8 6 2
8 4 1
5 8 7
7 2 8
3 1
2 3
3 3
1 3
2 1
1 4
1 1
2 4
3 2
2 2
1 2
3 4

输出样例:

1 1
3 4

正确代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,m,q;
	int x,y;
	cin>>n>>m>>q;
	int a[n+5][m+5],b[m+5][n+5];//记录每个人的好感度 
	vector<int> va[n+5],vb[m+5];//记录每个人访问到的好感度 
	int fa[n+5],fb[m+5];//记录是否已经被成立 
	memset(fa,0,sizeof(fa));
	memset(fb,0,sizeof(fb));
	int num=0;//约会成立人数
	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			cin>>b[i][j];
		}
	}
	while(q--){
		cin>>x>>y;
		va[x].push_back(a[x][y]);
		vb[y].push_back(b[y][x]);
		if(va[x].size()<3 || vb[y].size()<3) continue;
		int flag=0;//记录两人是否符合要求 
		if(va[x][va[x].size()-2] < a[x][y] && va[x][va[x].size()-3] < a[x][y]) flag++;
		if(vb[y][vb[y].size()-2] < b[y][x] && vb[y][vb[y].size()-3] < b[y][x]) flag++;
		if(!fa[x] && !fb[y]){
			num++;
			cout<<x<<" "<<y<<endl;
			fa[x]=1;
			fb[y]=1;
		}
	}
	if(num==0){//没有一对能约会成功
		cout<<"PTA is my only love"<<endl;
	}
	return 0;
} 

7-8 浪漫侧影 (25 分)

在这里插入图片描述

“侧影”就是从左侧或者右侧去观察物体所看到的内容。例如上图中男生的侧影是从他右侧看过去的样子,叫“右视图”;女生的侧影是从她左侧看过去的样子,叫“左视图”。

520 这个日子还在打比赛的你,也就抱着一棵二叉树左看看右看看了……

我们将二叉树的“侧影”定义为从一侧能看到的所有结点从上到下形成的序列。例如下图这棵二叉树,其右视图就是 { 1, 2, 3, 4, 5 },左视图就是 { 1, 6, 7, 8, 5 }。

fig.JPG

于是让我们首先通过一棵二叉树的中序遍历序列和后序遍历序列构建出一棵树,然后你要输出这棵树的左视图和右视图。

输入格式:

输入第一行给出一个正整数 N (≤20),为树中的结点个数。随后在两行中先后给出树的中序遍历和后序遍历序列。树中所有键值都不相同,其数值大小无关紧要,都不超过 int 的范围。

输出格式:

第一行输出右视图,第二行输出左视图,格式如样例所示。

输入样例:

8
6 8 7 4 5 1 3 2
8 5 4 7 6 3 2 1

输出样例:

R: 1 2 3 4 5
L: 1 6 7 8 5

正确代码:

在这里插入代码片
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值