PAT 520钻石争霸赛 2023(AK)

总结

感觉今年比去年简单很多。早上要去王道答疑上班,所以下午才能开始。但没想到AK后看排名只有20个AK,而且只有两位同学是9点整准时进入的,错失一盏台灯和50块钱代金券。简单题一笔带过,第七题偷懒被卡了。
在这里插入图片描述

第六题

11min

题意

询问n个数字,哪些符合情侣数。要求输出情侣数的数量,以及最大的情侣数。
情侣数:

  • 正整数、长度为偶数。
  • 元素分成两半,左半部分不严格单调递减,右半部分不严格单调递增。
  • 元素中存在至少一个偶数数字02468。
  • 各位和为奇数(左半部分和右半部分和的奇偶性不同)。

思路

  • 循环n次,每次先根据非正数、长度为奇数筛一遍。
  • 然后设置两个flag,一个用于判断是否有偶数元素,一个用于判断字符串元素是否先递减后递增。
  • 然后计算所有元素之和,奇数加偶数一定是奇数。
  • 根据两个flag和元素和可以判断该数是否是偶数。
#include<bits/stdc++.h>
using namespace std;
int main(){
	int n, ans = -1, cnt = 0; cin>>n;
	while(n--){
		int a; cin>>a;
		string sa = to_string(a);
		if(a <= 0 || sa.size() % 2 == 1) continue;
		bool f1 = false, f2 = true;
		for(int i = 0; i < sa.size();  i++)
			if((sa[i] - '0') % 2 == 0) f1 = true;
		for(int i = 1; i < sa.size() / 2; i ++)
			if(sa[i] > sa[i - 1]) f2 = false;
		for(int i = sa.size() / 2 + 1; i < sa.size(); i ++)
			if(sa[i] < sa[i - 1]) f2 = false;
		int sum = 0;
		for(int i = 0; i < sa.size(); i ++){
			sum += sa[i] - '0';
		}
		if(f1 && f2 && sum % 2 == 1){
			cnt ++;
			if(a > ans) ans = a;
		}
	}
	cout<<cnt<<endl;
	cout<<ans;
	return 0;
} 

第七题

25min

题意

给n对情侣,m个座位,座位序号1-n。
坐下后,如果两对情侣坐一起,两边的人吃狗粮。
如果不坐一起,夹在中间的人吃狗粮。
问谁吃的最多,如果吃的一样多,按编号从小到大输出。

思路

  • 先将情侣对以pair形式计入rec数组中。
  • int a[100010]记录怎么坐的,st数组记录该编号同学参加了。mts记录id对应同学的座位,比如100000同学坐在位置1,则mts[100000] == 1。stm记录座位对应同学的id。
  • 然后遍历rec,如果情侣双方都参加了,则不用吃狗粮,如果只有一方参加,则参与者仍被视为单身狗。
  • 再遍历rec,将坐在一起的情侣计入tmp,没坐一起的记左方位置l,右方位置r,用lr数组辅助区间求和lr[l + 1] ++; lr[r] --;
  • 根据lr数组和tmp完成区间和计算求出cnt数组,表示每个座位上的人吃到的狗粮数。
  • 顺序遍历找吃的最多的放到数组ans中。
  • 然后整理输出就可以啦~

小结

  • id、座位都是五位数则可以直接用int作为哈希表,这比STL的unordered_map快。
  • 偷懒想着应该不会考区间和,结果最后不得不推倒重写逻辑大改。其实这题很容易猜到就是考这个知识点的。

题解

#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
vector<pii> rec;
int n, l, r, a[100010], cnt[80001], mts[100010], stm[100010];
bool st[100010], ndog[100010];
int lr[100001];
int main(){
	cin>>n;
	while(n--){
		scanf("%d%d", &l, &r);
		rec.push_back({l, r});
	}
	cin>>n;
	for(int i = 1; i <= n; i ++){
		scanf("%d", &a[i]);
		st[a[i]] = true;
		mts[a[i]] = i;
		stm[i] = a[i];
	}
	for(auto i : rec){
		if(st[i.first] && st[i.second]){
			ndog[i.first] = true;
			ndog[i.second] = true;
		}
	}
	vector<pii> tmp;
	for(auto i : rec){
		l = mts[i.first], r = mts[i.second];
		if(l > r) swap(l, r);
		if(l && r){
			if(r - l == 1){
				tmp.push_back({l, r});
			}else{
				lr[l + 1] ++;
				lr[r] --;
			}
		}
	}
	for(int i = 1; i <= n; i++){
		cnt[i] = cnt[i - 1] + lr[i];
	}
	for(auto i : tmp){
		cnt[i.first - 1] ++;
		cnt[i.second + 1] ++;
	}
	vector<int> ans, out;
	int bad = -1;
	for(int i = 1; i <= n ;i ++){
		if(ndog[stm[i]]) continue;
		if(cnt[i] > bad){
			bad = cnt[i];
			ans.clear();
			ans.push_back(stm[i]);
		}else if(cnt[i] == bad){
			ans.push_back(stm[i]);
		}
	}
	sort(ans.begin(), ans.end());
	for(int i = 0; i < ans.size(); i ++){
		printf("%05d%c", ans[i], i == ans.size() - 1 ? '\n' : ' ');
	}
	
	return 0;
} 

题目

sgl.jpg

网络上称一对情侣秀恩爱为“撒狗粮”,因为单身人士统称为“单身狗”。
在一个大型聚会上,所有宾客被安排坐在一张长条宴会桌边。如果一对情侣坐在一起,那么他们两人身边的单身狗就会被撒一脸狗粮;如果他们没有坐在一起,那么所有被夹在他们两人之间的单身狗都会被撒一脸狗粮。
本题就请你找出被撒狗粮最多(以“脸”为单位)的那位单身人士。

输入格式:

输入第一行给出一个正整数 N(≤ 50 000),是已知情侣的对数;随后 N 行,每行给出一对情侣——为方便起见,每人对应一个 ID 号,为 5 位数字(从 00000 到 99999),ID 间以空格分隔;之后给出一个正整数 M(≤ 80 000),为参加派对的总人数;随后一行按座位从左到右的顺序给出这 M 位客人的 ID,以空格分隔。题目保证无人脚踩两条船。

输出格式:

在一行中输出被撒狗粮最多的单身人士。如果不唯一,按 ID 递增顺序列出。ID 间用 1 个空格分隔,行的首尾不得有多余空格。
题目保证至少有一个输出。

输入样例:

4
11111 22222
33333 44444
55555 66666
77777 88888
10
11111 33333 88888 22222 23333 55555 66666 10000 44444 12345

输出样例:

10000 23333 88888

注意:88888 虽然有伴侣,但在聚会上是单身。

第八题

7min

小结

  • 直接int数组作为哈希表比unordered_map快,但是为什么待深究。
  • 被cin卡时间了,反应慢了点。
#include<bits/stdc++.h>
using namespace std;
int mp[100001000];
int main(){
	int n, m; cin>>n;
	for(int i = 1; i <= n; i++){
		int a; scanf("%d", &a);
		mp[a] = i;
	}
	cin>>m;
	for(int i = 0; i < m; i ++){
		int b; scanf("%d", &b);
		if(mp[b] != 0) printf("%d\n", mp[b]);
		else puts("Sorry");
	}
	return 0;
} 

第一题

1min

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n; cin>>n;
    cout<<"520 "<<n<<" Times!";
	return 0;
} 

第二题

2min

#include<bits/stdc++.h>
using namespace std;
int main(){
	int a, b, t;
	cin>>t>>a>>b;
	if(a >= t && b >= t) puts("*^_^*");
	else if(a >= t && b < t) puts("T_T");
	else if(a < t && b >= t) puts("-_-#");
	else puts("-_-");
	return 0;
} 

第三题

2min

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n; cin>>n;
	while(n--){
		int k; cin>>k;
		puts(k % 2 == 0 ? "!Love" : "Love!");
	}
	return 0;
} 

第四题

4min

#include<bits/stdc++.h>
using namespace std;
int n, m, a, b, k, g[13][13];
int main(){
	for(int i = 1; i < 13; i ++){
		cin>>n;
		cin>>k;
		while(k--){
			cin>>m;
			g[n][m] = g[m][n] = 1;
		}
		cin>>k;
		while(k --){
			cin>>m;
			g[n][m] = g[m][n] = -1;
		}
	}
	cin>>n;
	while(n--){
		cin>>a>>b;
		if(g[a][b] == 1)puts("Yes");
		else if(g[a][b] == -1) puts("No");
		else puts("NA");
	}
	return 0;
} 

第五题

4min

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n; cin>>n;
	while(n--){
		string a, b; cin>>a;
		bool flag = true;
		for(int i = 0; i < a.size(); i ++){
			if(a[i] == '0' || a[i] == '1' || a[i] == '8') b += a[i];
			else if(a[i] == '6') b += "9";
			else if(a[i] == '9') b += "6";
			else{
				flag = false;
				puts("bu ke neng");
				break;
			}
		}
		if(flag == true) cout<<b<<endl;
	}
	return 0;
} 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值