PAT(甲级)2019年春季考试
7-1 Sexy Primes (20分)
题意:判断 n 和 n + 6 或者 n 和 n -6 是不是素数
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5;
int n;
bool isPrime(int n)
{
if(n<=1) return 0;
for(int i=2; i*i<=n; ++i)
if(n%i==0) return 0;
return 1;
}
bool check(int a,int b)
{
return isPrime(a)&&isPrime(b);
}
int main()
{
scanf("%d",&n);
if(check(n,n-6))
{
puts("Yes");
printf("%d\n",n-6);
}
else if(check(n,n+6))
{
puts("Yes");
printf("%d\n",n+6);
}
else
{
int ans=n;
while(1)
{
n++;
if(check(n,n-6)) break;
}
puts("No");
if(ans<n-6) ans=n-6;
else ans=n;
printf("%d\n",ans);
}
return 0;
}
7-2 Anniversary (25分)
题意:给定一些身份证号,判断是不是校友,输出校友的数量。并输出最老的校友
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5;
int n,m;
set<string> st1,st2,st3;
string s;
int main()
{
cin>>n;
for(int i=1; i<=n; ++i)
{
cin>>s;
st1.insert(s);
}
cin>>m;
while(m--)
{
cin>>s;
st2.insert(s);
if(st1.count(s)) st3.insert(s);
}
m=st3.size();
printf("%d\n",m);
if(m==0)
{
set<string> st4;
for(auto x: st2)
{
st4.insert(x.substr(6,7));
}
for(auto x: st2)
{
if(x.substr(6,7)==*st4.begin())
{
cout<<x<<"\n";
break;
}
}
}
else
{
set<string> st4;
for(auto x: st3)
{
st4.insert(x.substr(6,7));
}
for(auto x: st3)
{
if(x.substr(6,7)==*st4.begin())
{
cout<<x<<"\n";
break;
}
}
}
return 0;
}
7-3 Telefraud Detection (25分)
题意:给定一些通话记录,判断是哪些人是诈骗犯。并且判断是不是在同一个团伙中。如果一个人 打了超过 k 个不到 5 分钟的电话,并且回拨的电话数量少于 20%,则这个人是诈骗犯。如果两个诈骗犯相互打电话,则他们是同伙。输出每一个犯罪团体,并且按照最小的 id 排序
思路:先找到同伙,然后用并查集处理分类。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1010;
int k,n,m;
int call[maxn],rece[maxn];
int sup[maxn],mp[maxn][maxn];
set<int> st;
int pa[maxn],col[maxn];
int find(int x)
{
return pa[x]==x?x:pa[x]=find(pa[x]);
}
void merge(int u,int v)
{
int ru=find(u),rv=find(v);
if(ru!=rv)
{
if(ru<rv) swap(ru,rv);
pa[ru]=rv;
}
}
int main()
{
cin>>k>>n>>m;
for(int i=1; i<=m; ++i)
{
int u,v,w;
cin>>u>>v>>w;
mp[u][v]+=w;
}
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
{
if(mp[i][j]<=5&&i!=j&&mp[i][j]!=0)
{
call[i]++;
if(mp[j][i]!=0) rece[i]++;
}
}
vector<int> vec;
for(int u=1; u<=n; ++u)
if(call[u]>k&&rece[u]*5<=call[u]) sup[u]=1,vec.push_back(u);
m=vec.size();
for(int i=1; i<=m; ++i) pa[i]=i;
for(int i=1; i<=m; ++i)
for(int j=1; j<=m; ++j)
if(i!=j&&mp[vec[i-1]][vec[j-1]]!=0&&mp[vec[j-1]][vec[i-1]]!=0)
merge(i,j);
int cnt=0;
vector<int> ans[maxn];
for(int i=1; i<=m; ++i)
{
int ru=find(i);
if(!col[ru]) col[ru]=++cnt;
ans[col[ru]].push_back(vec[i-1]);
}
for(int i=1; i<=cnt; ++i)
{
int m=ans[i].size();
for(int j=1; j<=m; ++j) printf("%d%c",ans[i][j-1],j==m?'\n':' ');
}
if(cnt==0) puts("None");
return 0;
}
7-4 Structure of a Binary Tree (30分)
题意:给定中序和后序创建二叉树,并对相应的表述做判断。
思路:老旧的题目,做过很多遍了。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5;
int n,m;
int a[maxn],b[maxn];
struct Node
{
int val,depth;
Node* ls,* rs,* fa;
};
Node* build(int l1,int r1,int l2,int r2,int depth,Node* fa)
{
if(l1>r1) return NULL;
int pos;
for(pos=l2; pos<=r2; ++pos)
if(b[pos]==a[r1]) break;
int len1=pos-l2;
int len2=r2-pos;
Node* node=new Node;
node->val=a[r1];
node->depth=depth;
node->fa=fa;
node->ls=build(l1,l1+len1-1,l2,pos-1,depth+1,node);
node->rs=build(l1+len1,r1-1,pos+1,r2,depth+1,node);
return node;
}
Node* find(Node* rt,int x)
{
if(rt==NULL) return NULL;
if(rt->val==x) return rt;
Node* tmp=find(rt->ls,x);
if(tmp!=NULL) return tmp;
return find(rt->rs,x);
}
bool ok=1;
void dfs(Node* root)
{
if(root==NULL) return;
if(root->ls==NULL&&root->rs!=NULL||root->ls!=NULL&&root->rs==NULL)
ok=0;
dfs(root->ls);
dfs(root->rs);
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; ++i) scanf("%d",&a[i]);
for(int i=1; i<=n; ++i) scanf("%d",&b[i]);
Node* root=build(1,n,1,n,1,NULL);
scanf("%d",&m);
getchar();
while(m--)
{
string s;
int x,y;
getline(cin,s);
if(s.find("root")!=-1)
{
sscanf(s.c_str(),"%d is the root",&x);
puts(root->val==x?"Yes":"No");
}
else if(s.find("siblings")!=-1)
{
sscanf(s.c_str(),"%d and %d are siblings",&x,&y);
Node* a=find(root,x);
Node* b=find(root,y);
if(a!=NULL&&b!=NULL&&a->fa==b->fa) puts("Yes");
else puts("No");
}
else if(s.find("parent")!=-1)
{
sscanf(s.c_str(),"%d is the parent of %d",&x,&y);
Node* a=find(root,x);
Node* b=find(root,y);
if(a!=NULL&&b!=NULL&&a==b->fa) puts("Yes");
else puts("No");
}
else if(s.find("left")!=-1)
{
sscanf(s.c_str(),"%d is the left child of %d",&x,&y);
Node* a=find(root,x);
Node* b=find(root,y);
if(a!=NULL&&b!=NULL&&a==b->ls) puts("Yes");
else puts("No");
}
else if(s.find("right")!=-1)
{
sscanf(s.c_str(),"%d is the right child of %d",&x,&y);
Node* a=find(root,x);
Node* b=find(root,y);
if(a!=NULL&&b!=NULL&&a==b->rs) puts("Yes");
else puts("No");
}
else if(s.find("level")!=-1)
{
sscanf(s.c_str(),"%d and %d are on the same level",&x,&y);
Node* a=find(root,x);
Node* b=find(root,y);
if(a!=NULL&&b!=NULL&&a->depth==b->depth) puts("Yes");
else puts("No");
}
else if(s.find("full")!=-1)
{
ok=1;
dfs(root);
puts(ok?"Yes":"No");
}
}
return 0;
}