2020 PAT甲级春季考试解题报告(满分)

前言

       刷了不到20道真题就去考PAT了(勇士精神 )。话说13点30分对于午觉党来说真的不太友好,很容易犯食困。。。

题解

第一题

  • 给你一个日期字符串,判断所有后缀字符串对应的数字是否是素数。暴力模拟一下即可。
#include
using namespace std;
typedef long long ll;
ll d[20], cnt = 0;
bool ans[20];
void trans(string s){
	int i, j, x = 0;
	for(i=7;i>=0;--i){
		for(j=i;j<=7;++j){
			d[i] *= 10;
			d[i] += s[j] - '0';
		}
	}
}
bool judge(ll num){
	ll k = sqrt(num + 0.5), i;
	if(num == 1) return false;
	for(i=2;i<=k;++i){
		if(num % i == 0) break;
	}
	return i > k;
}
void solve(){
	int i, j;
	for(i=0;i<=7;++i){
		if(judge(d[i])){
			cnt++;
			ans[i] = true;
		}
	}
}
int main(){
	string s;
	int i;
	ios::sync_with_stdio(false);
	cin>>s;
	trans(s);
	solve();
	for(i=0;i<=7;++i){
		cout<<s<<' ';
		if(ans[i]){
			cout<<"Yes\n";
		}else{
			cout<<"No\n";
		}
		s.erase(s.begin());
	}
	if(cnt == 8){
		cout<<"All Prime!\n";
	}
	return 0;
}

第二题

  • 模拟题。
  • 有一个游戏,最开始给两个数字。然后有 n n n个人,共 m m m个回合。在每一个回合中,由当前玩家指定一个数,要求这个数不能与前面的重复并且必须是前面的所有数字中的某两个数的差值,如果不满足,当前玩家出局。最后问有哪些玩家在什么时候出局了。
  • 思路:用一个flag数组标记一下在哪个回合出局,用一个哈希表存一下已有的数的映射便于判断当前玩家的数字是否满足条件,用exist数组表示已有的数字。一开始用map超时了,改成unordered_map也超时了,才注意到原来范围只有10万,于是用改成数组就过了。(只要是个出题人都会卡unordered_map系列)
#include
using namespace std;
typedef long long ll;
const int maxn = 1010;
int x, y, n, m;
vector<int> M[15];
int flag[15]; //是否出局 
vector<int> exist;
int maxi = 0;
int mp[100100];
bool judge(int v){ //是否符合条件 
	int i, j, k, sz = exist.size();
	if(mp[v]) return false;
	for(i=0;i<sz;++i){
		int e = exist[i];
		if(e + v > 100000) continue;
		if(mp[e+v]){
			break;
		}
	}
	return i < sz;
}
void solve(){
	int i, j, k;
	exist.push_back(x);exist.push_back(y);
	maxi = max(x, y);
	mp[x] = 1;mp[y] = 1;
	for(k=0;k<m;++k){ //m轮回合 
		for(i=1;i<=n;++i){ //第i个人 
			if(!flag[i]){ //未出局 
				if(judge(M[i][k])){
					exist.push_back(M[i][k]);
					mp[M[i][k]] = 1;
				}else{
					flag[i] = k + 1;
				}
			}
		}
	}
}
int main(){
	int i, j, t;
	ios::sync_with_stdio(false);
	cin>>x>>y>>n>>m;
	for(i=1;i<=n;++i){
		for(j=1;j<=m;++j){
			cin>>t;
			M[i].push_back(t);
		}
	}
	solve();
	
	for(i=1;i<=m;++i){
		vector<int> ans;
		for(j=1;j<=n;++j){
			if(flag[j] == i){
				ans.push_back(j);
			}
		}
		if(ans.empty()) continue;
		int sz = ans.size();
		for(j=0;j<sz;++j)
			cout<<"Round #"<<i<<": "<<ans[j]<<" is out.\n"; 
	}
	vector<int> temp;
	for(i=1;i<=n;++i){
		if(!flag[i]) temp.push_back(i);
	}
	if(temp.empty()){
		cout<<"No winner.";
	}else{
		cout<<"Winner(s): ";
		cout<<temp[0];
		for(j=1;j<temp.size();++j) cout<<' '<<temp[j];
	}
	return 0;
}

第三题

  • 判断图中相邻结点的元素值是否相等
  • 留意一下species多和少的情况
  • 建完图遍历一遍就ok了
#include
using namespace std;
typedef long long ll;
const int maxn = 510;
int n, m, r, k;
int G[maxn][maxn], a[maxn], x[maxn];
bool judge(){
	int i, j;
	for(i=1;i<=n;++i){
		for(j=i+1;j<=n;++j){
			if(G[i][j] && x[i] == x[j]){
				return false;
			}
		}
	}
	return true;
}
int main(){
	int i, j, t, u, v;
	ios::sync_with_stdio(false);
	cin>>n>>r>>k;
	for(i=1;i<=r;++i){
		cin>>u>>v;
		G[u][v] = G[v][u] = 1;
	}
	cin>>m;
	for(i=1;i<=m;++i){
		memset(a, 0, sizeof(a));
		int cnt = 0;
		for(j=1;j<=n;++j){
			cin>>u;
			x[j] = u;
			if(!a[u]){
				++cnt;
				a[u] = 1;
			}
		}
		if(cnt > k){
			cout<<"Error: Too many species.\n";
		}else if(cnt < k){
			cout<<"Error: Too few species.\n";
		}else{
			if(judge()){
				cout<<"Yes\n";
			}else{
				cout<<"No\n";
			}
		}
	} 
	return 0;
}

第四题

  • 模拟一下外部排序Replace Selection(置换选择算法)的过程
  • 思路:建立两个优先权队列Q和q,Q存放当前runs,然后如果碰到后面的数字更小则往q里面存;如果当前的runs已经没了(Q为空),则交换Q和q的值,再迭代下去。考场上懒得思考,直接暴力覆盖了一下边界条件,所以代码显得有些冗长。
#include
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
priority_queue<int, vector<int>, greater<int> > Q, q;
vector<int> ans[maxn];
int n, m, a[maxn], tag = 1;
void solve(){
	int i, j;
	for(i=1;i<=m;++i) Q.push(a[i]);
	int cnt = m + 1;
	while(cnt <= n){
		if(Q.empty()){ //当前队列空 
			while(!q.empty()){
				Q.push(q.top());
				q.pop();
			}
			tag++; 
		}
		if(Q.empty()) return;
		int e = Q.top();Q.pop();
		ans[tag].push_back(e);
		if(a[cnt] < e){
			q.push(a[cnt]);
		}else{
			Q.push(a[cnt]);
		}
		++cnt;
	}
	if(Q.empty()){ //当前队列空 
		while(!q.empty()){
			Q.push(q.top());
			q.pop();
		}
		tag++; 
	}
	while(!Q.empty()){
		int e = Q.top();Q.pop();
		ans[tag].push_back(e);
	}
	if(Q.empty()){ //当前队列空 
		while(!q.empty()){
			Q.push(q.top());
			q.pop();
		}
		tag++; 
	}
	while(!Q.empty()){
		int e = Q.top();Q.pop();
		ans[tag].push_back(e);
	}
}
int main(){
	int t, i, j;
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(i=1;i<=n;++i) cin>>a[i];
	solve();
	for(i=1;i<=tag;++i){
		sort(ans[i].begin(),ans[i].end());
	}
	for(i=1;i<=tag;++i){
		if(ans[i].empty()) continue;
		cout<<ans[i][0];
		for(j=1;j<ans[i].size();++j){
			cout<<' '<<ans[i][j];
		}
		cout<<'\n';
	}
	return 0;
}

你可能感兴趣的:(算法竞赛题解,算法)