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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值