【PAT甲级最新题解】PAT甲级2020.7月春季考试满分题解(附代码)

【PAT甲级最新题解】PAT甲级2020.7月春季考试满分题解(附代码)_第1张图片

写在前面:这次题目虽然大多数是模拟题且不算难,但是题面其实不算友好,不少同学因为题目描述而错失满分。


A:

题意:给定一个数字串,问每一个前缀串是否是素数。

模拟题不多解释。

#include
#include
#include
#include
#include
#include
#include

using namespace std;
const int MAX = 2e5 + 6;
string s;
bool isprime(int x) {
	if(x < 2) return 0;
	for(int i = 2; i*i<=x; i++) {
		if(x%i == 0) return 0;
	}
	return 1;
}
int main()
{
	cin>>s;
	int len = s.length();
	int flag = 1;
	for(int i = 0; i

B:

题意:n个人玩牌m盘。刚开始桌子上有两张牌,每盘中依次轮每个人出牌,牌放到桌子上,每一盘中这个人不出局当且仅当这个人出的牌桌子上都没有,并且恰好为桌子上某两个牌的数值的差的绝对值。然后按要求输出每一盘出局的人以及最后是否有winner。

题面是真的坑,刚开始在输出格式这里卡了半天,好在最后AC了。

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAX = 4e5 + 6;

int a,b;
int n,m;
int val[102][1003];
int out[102];//是否出局 
vector hx;//候选的数字
vector vv;//每一局淘汰的人 
bool is[MAX],diff[MAX];
int main()
{
	cin>>a>>b;
	cin>>n>>m;
	for(int i = 1; i<=n; i++) {
		for(int j = 1; j<=m; j++) {
			scanf("%d",&val[i][j]);
		}
	}
	is[a]=1;is[b]=1;
	diff[abs(a-b)]=1;
	hx.push_back(a);
	hx.push_back(b);
	int cnt_out = 0;
	for(int j = 1; j<=m; j++) {//每一局 
		vv.clear();
		for(int i = 1; i<=n; i++) {//每个人 
			if(out[i] == 1) continue;
			int now = val[i][j];
			int jixu = diff[now];
			if(is[now] == 1) jixu = 0;
			if(jixu == 1) is[now] = 1;//这里加不加if都能AC,但是题面意思并不清晰。 
			if(jixu == 0) {
				cnt_out++;
				out[i] = 1;
				vv.push_back(i);
				continue;
			}
			for(int k = 0; k 0) {
			for(int k = 0; k

C:

题意:给一张无向图,相邻点不能是相同颜色,给你m种染色方案,问你每一种是否合法。

经典的染色问题,求解是np的,但是验证解是线性的,水题。

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAX = 4e5 + 6;
int val[MAX];
int n,r,k,m;
pair pr[MAX];
set ss;
int main()
{
	cin>>n>>r>>k;
	for(int a,b,i = 1; i<=r; i++) {
		scanf("%d%d",&a,&b);
		pr[i].first = a;
		pr[i].second = b;
	}
	cin>>m;
	for(int i = 1; i<=m; i++) {
		ss.clear();
		for(int j = 1; j<=n; j++) {
			scanf("%d",&val[j]);
			ss.insert(val[j]);
		}
		if(ss.size() > k) {
			printf("Error: Too many species.\n");
		}
		else if(ss.size() < k) {
			printf("Error: Too few species.\n");
		}
		else {
			int flag = 1;
			for(int a,b,q = 1; q<=r; q++) {
				a = pr[q].first;
				b = pr[q].second;
				if(val[a] == val[b]) {flag = 0;break;}
			}
			if(flag == 1) puts("Yes");
			else puts("No");
			
		}
	}

}
/*
6 8 3
2 1
1 3
4 6
2 5
2 4
5 4
5 6
3 6
5
1 2 3 3 1 2
1 2 3 4 5 6
4 5 6 6 4 5
2 3 4 2 3 4
2 2 2 2 2 2
*/

D:

题意:定义了一种排序方式,让你用这种排序方式把给定的数字进行排序。

做法:拿个set维护窗口内的数就可以了,不难。

注意题面是int范围,也就是代表可以有负数。(是-1e11啊不是1e-11,Orz)

这题刚开始一直T,本来想是不是卡了log,强行让你用并查集进行区间合并,交卷还剩半小时的时候发现是自己写挂了,log是可以过的。

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAX = 2e5 + 6;
int n,m,ok[MAX];
ll a[MAX];
set > ss;
set ori;
set cur;
vector vv; 
vector > cc;
int f[MAX];
int getf(int v) {
	return f[v] == v ? v : f[v] = getf(f[v]);
}
int main()
{
	cin>>n>>m;
	for(int i = 1; i<=n; i++) scanf("%lld",a+i),f[i]=i,ori.insert(i);
	int cur_ans = 0;
	for(int times = 1; times<=n; times++) {
		ss.clear();vv.clear();cc.clear();
		pair last = make_pair((ll)-1e11,0);
		for(set::iterator itt = ori.begin(); itt != ori.end(); ++itt) {
			int pos = *itt; 
			if(ss.size() < m) {
				ss.insert(make_pair(a[pos],pos));
			}
			if(ss.size() == m) {
				set >::iterator it = ss.lower_bound(last);
				if(it == ss.end()) {
					break;
				}
				else {
					pair now = *it;
					cc.push_back(now.second);
					vv.push_back(now.first);
					ss.erase(it);
					last = now;
				}
			}
		}
		set >::iterator it = ss.lower_bound(last);
		for(;it != ss.end(); ++it) {
				pair now = *it;
				cc.push_back(make_pair(now.second,now.first));
				ok[now.second] = 1;
				vv.push_back(now.first);
				//ss.erase(it);
				last = now;			
		}
		
		int up = vv.size();
		cur_ans += up;
		for(int i = 0; i

有不懂的地方欢迎评论一起讨论~

 


另外,如果你要问我怎么发现的输出格式的问题,那么下面这张图将回答这个问题:

【PAT甲级最新题解】PAT甲级2020.7月春季考试满分题解(附代码)_第2张图片

你可能感兴趣的:(PAT)