PTA 2021---520钻石争霸赛题解

7-1自动编程

铁签到题…为了简单python直接上…

x = input()
print("print(%s)"%x)

7-2 加油冲鸭

题意解析(也不太用说了吧):
给你长度以及跑的速度及时间,然后求还剩多少米没跑,按照要求输出
签到题2

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
	int n,m,s;
	cin>>n>>m>>s;
	int cur = m*s;
	printf("hai sheng %d mi! ",n - cur);
	if(cur >= n/2)
	printf("chong ya!");
	else
	printf("jia you ya!");
}

7-3 520的表白

输入一行,然后输出520次
第二个铁签到题,python上!

m = input()
i = 0
while i < 520:
    print(m)
    i += 1

7-4 奇葩楼层

按照一般规律,这种题一般要卡一下暴力的
但是PTA一般不讲武德,不需要找出规律,直接暴力即可
下面就先贴出暴力的代码8,之后再补规律代码…

#include <iostream> 
using namespace std;
int main()
{
	int n,d;
	scanf("%d %d",&n,&d);
	int ans = 0;
	for(int i=1;i <= n;i++)
	{
		int t = i;
		int f =0 ;
		while(t)
		{
			if(t%10 == d)
			{
				f =  1;
				break;
			}
			t /=  10;
		}
		if(f)
		continue;
		ans ++ ;
	}
	cout<<ans;
	return 0;
}

7-5 大勾股定理

题意解读:
给你一个数n,要你求出连续的2n + 1段序列,这段序列是由一些正整数的平方构成的,而且要求前n + 1个的和等于后n个的和
很容易就想到先求到一定数量的平方数前缀和,然后再暴力枚举中间点(前n + 1最后的那个数字),然后O(1)复杂度判断一下,具体前缀和判断式子就是 sum[i] - sum[i - n - 1] == sum[i + n] - sum[i]
那么就先交一发吧,果然,这会聪明了,卡了一个一分的点(超时…)
那就打个表吧,发现我们寻找的那个中间点和n有下面这样的关系
n = 1,2,3,4…
i(中间点) = 4,12,24,40
很容易求得这个*i = 2*(n + 1)n
因此我们找到 i 剩下的就是两个for循环的输出咯…
附打表代码~~

#include <iostream>
using namespace std;
const int MAXN = 100005;
typedef long long ll;
ll a[MAXN];
ll sum[MAXN];
int main()
{
//	for(int i=1;i < MAXN;i++)
//	a[i] = i*i,sum[i] = sum[i - 1] + a[i];
	
	int n;
	scanf("%d",&n);
//	for(int k = 1;k <= n;k++)
	int k = 4;
	int now = 2*n*(n + 1);
	
//	for(int k = 1;k <= n;k++)
	int i = now;
//	for(int i = k + 1;i + k < MAXN;i++)
	{
//		if(sum[i] - sum[i - k - 1] == sum[i + k] - sum[i])
		{
//			cout<<i<<endl;
//			break;
//			return 0;
			for(int j = i-n;j <= i;j++)
			{
				if(j != i)
				printf("%d^2 + ",j);
				else
				printf("%d^2 =\n",j);
			}
			for(int j = i + 1;j <= i + n;j++)
			{
				if(j != i + n)
				printf("%d^2 + ",j);
				else
				printf("%d^2",j);
			}
			return 0;
		}
	}
}

7-6 矩阵列平移

这个题和之前的一个乙级题目很像…好像那个叫行平移…一个意思
简单模拟…

#include <iostream>
using namespace std;
const int MAXN = 105;
int a[MAXN][MAXN];
int main()
{
	int n,k,x;
	scanf("%d %d %d",&n,&k,&x);
	for(int i=1;i <= n;i++)
	for(int j = 1;j <= n;j++)
	scanf("%d",&a[i][j]);
	
	int K = 1;
	for(int j = 2;j <= n;j+=2)
	{
		K %= k;
		if(K == 0)
		K = k;
		{
			for(int i = n;i > K;i--)
			a[i][j] = a[i-K][j];
			
			for(int i=1;i <= K;i++)
			a[i][j] = x;
		}
		K += 1;
	}
//	for(int i=1;i <= n;i++)
//	{
//		
//	for(int j = 1;j <= n;j++)
//	printf("%d%c",a[i][j]," \n"[j == n]);
//	}
	int ans = 0;
	int f = 0;
	for(int i=1;i <= n;i++)
	{
		ans = 0;
		for(int j=1;j <= n;j++)
		ans += a[i][j];
		
		if(!f)
		printf("%d",ans);
		else
		printf(" %d",ans);
		f = 1;
	}
	return 0;
}

7-7 约会大作战

题意解读:
给你一串规则,然后输入一堆人,让你模拟判断这一堆人谁能出现(凑成一对)
规则如下:
1.先前的两个询问都没用
2.第三个询问开始,如果当前询问的这个人的好感度大于之前两个人的好感度,那么这个人就OK
3.如果当前询问的这两个人都OK的话,那么他俩是真OK,就可以输出了
细节:
这里注意第是前两个人,例如当第四次询问这个人的时候,他还没有脱单,那么就是拿第三次询问以及第二次询问的值来比较(当然我们只用拿那个最大的对比一下就行)…

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
	int n,m,q;
	scanf("%d %d %d",&n,&m,&q);
	
	int a[n][m];
	int b[m][n];
	for(int i=0;i < n;i++)
	for(int j=0;j < m;j++)
	scanf("%d",&a[i][j]);
	
	for(int i=0;i < m;i++)
	for(int j=0;j < n;j++)
	scanf("%d",&b[i][j]);
	
	int ls1[n][501],ls2[n][501];
	int c1[n],c2[n];
	int dot1[n],dot2[n];
	memset(dot1,0,sizeof dot1);
	memset(dot2,0,sizeof dot2);
	memset(c1,0,sizeof c1);
	memset(c2,0,sizeof c2);
	
	int count = 0;
	while(q--)
	{
		int x,y;
		cin>>x>>y;
		x -= 1;
		y -= 1;
		
		ls1[x][c1[x]++] = a[x][y];
		ls2[y][c2[y]++] = b[y][x];
		
		if(dot1[x] || dot2[y])	continue;
		if(c1[x] < 3 || c2[y] < 3)continue;
		
		int Max1 = max(ls1[x][c1[x] - 2],ls1[x][c1[x] - 3]);
		int Max2 = max(ls2[y][c2[y] - 2],ls2[y][c2[y] - 3]);
        if(a[x][y] > Max1 && b[y][x] > Max2)
		{
			count += 1;
			printf("%d %d\n",x + 1,y + 1);
			dot1[x] = 1;
			dot2[y] = 1;
		}
	}
	if(!count)
	cout<<"PTA is my only love";
	return 0;
}

7-8 浪漫侧影

暴力中序以及后续遍历的建图
然后层序遍历,左视图就是取层序遍历最左端的
右视图就是取层序遍历最右边的
都是板子我这里就不过多解释啦…

#include <iostream>
using namespace std;
const int MAXN = 25;
int a[MAXN];
int b[MAXN];
struct node
{
	int data;
	int le,ri;
	node(){
		le = ri = -1;
	}
}t[MAXN];
void build(int le1,int ri1,int le2,int ri2)//前序和中序 
{
	int root = a[ri1];
	int i = le2;
	while(b[i] != root)
	i += 1;
	
	int le = i - le2;
	int ri = ri1 - le1 - le;
	
	if(le)
	{
		t[ri1].le = ri1 - ri - 1;
		build(le1,le1 + le - 1,le2,i - 1);
	}
	if(ri)
	{
		t[ri1].ri = ri1 - 1;
		build(le1 + le,ri1 - 1,i + 1,ri2);
	}
}
int L[MAXN],t1;
int R[MAXN],t2;
	int n;
void Go()
{
	int que[MAXN*100],head = 0,tail = 0;
	que[tail++] = n - 1;
	while(tail != head)
	{
		int size = tail - head;
		L[t1++] = t[que[head]].data;
		while(size--)
		{
			int now = que[head++];
			if(size == 0)
			R[t2++] = t[now].data;
			
			if(t[now].le != -1)
			que[tail++] = t[now].le;
			if(t[now].ri != -1)
			que[tail++] = t[now].ri;
		}
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=0;i < n;i++)
	scanf("%d",&b[i]);
	for(int i=0;i < n;i++)
	scanf("%d",&a[i]),t[i].data = a[i];
	
	build(0,n-1,0,n-1);
	Go();
	
	printf("R:");
	for(int i=0;i < t2;i++)
	printf(" %d",R[i]);
	
	puts("");
	
	printf("L:");
	for(int i=0;i < t1;i++)
	printf(" %d",L[i]);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值