PAT(甲级)2019年春季考试

本文深入探讨了算法在实际问题中的应用,包括周年纪念日日期比较、电话欺诈检测策略以及二叉树结构的构建与验证。通过实例展示了如何使用C++实现这些算法,涉及字符串处理、集合操作、并查集和二叉树的性质。此外,还讨论了素数及其相邻素数的寻找方法。
摘要由CSDN通过智能技术生成

7-2 Anniversary


#include<iostream>
#include<set>
using namespace std;

const int maxn=100010;

int n,m;

set<string> s1,s2;

int main()
{
    cin >> n;
    for(int i=0; i<n; i++)
    {
        string s;
        cin >> s;
        s1.insert(s);
    }

    cin >> m;
    int cnt=0;
    string old,oldg;
    int miny=9999,mind=99,minm=99;
    int minyg=9999,mindg=99,minmg=99;
    for(int i=0; i<m; i++)
    {
        string s;
        cin >> s;
            int y=stoi(s.substr(6,4));
            int m=stoi(s.substr(10,2));
            int d=stoi(s.substr(12,2));
            if(minyg>y)
            {
                minyg=y;
                oldg=s;
            }
            else if(minyg==y && minmg>m)
            {
                minmg=m;
                oldg=s;
            }
            else if(minyg==y && minmg==m && mindg>d)
            {
                mindg=d;
                oldg=s;
            }



        if(s1.find(s)!=s1.end())
        {
            cnt++;
            int y=stoi(s.substr(6,4));
            int m=stoi(s.substr(10,2));
            int d=stoi(s.substr(12,2));
            if(miny>y)
            {
                miny=y;
                old=s;
            }
            else if(miny==y && minm>m)
            {
                minm=m;
                old=s;
            }
            else if(miny==y && minm==m && mind>d)
            {
                mind=d;
                old=s;
            }
        }
    }
    if(cnt)
    {
        cout << cnt << endl << old;
    }
    else
    {
        cout << cnt << endl << oldg;
    }

}

7-3 Telefraud Detection

#include <bits/stdc++.h>

using namespace std;

int cnt[1024][1024];        //用一个二维数组存放信息

vector<int> vs;     //vis存放所有的嫌疑人

int parents[1024];   //这个就是并查集的父亲节点

int finds(int x)        //并查集的函数
{
    if(x!=parents[x])
        parents[x]=finds(parents[x]);
    return parents[x];
}

int main()
{
    int k, n, m;        //读入k,n,m
    
    scanf("%d %d %d", &k, &n, &m);

    for(int i = 0; i < m; i++)
    {
        int c, r, d;
        scanf("%d %d %d", &c, &r,&d);
        cnt[c][r] += d;
    }

    for(int i = 1; i <= n; i++)
    {
        int sum = 0, rsum = 0;      //sum是打出的电话数,rsum是回应的电话数
        for(int j = 1; j <= n; j++)
        {
            if(cnt[i][j] > 0 && cnt[i][j] <= 5)
            {
                sum++;
                if(cnt[j][i] > 0) rsum++;//统计回电话人数
            }
        }
        if(sum > k )
        {
            vs.push_back(i);
            if(sum > 0 && 1.0 * rsum / sum > 0.2) vs.pop_back();//去除回电话数大于20%的嫌疑人
        }
    }

    for(int i = 1; i <= n; ++i)
    {
        parents[i] = i;                        //对并查集的父亲节点出初始化
    }

    int sz = vs.size();

    for(int i = 0; i < sz; i++)
    {
        for(int j = i + 1; j < sz; j++)
        {
            if(cnt[vs[i]][vs[j]] > 0 && cnt[vs[j]][vs[i]] > 0){//嫌疑人之间有相互联系
                int L1 = finds(vs[i]), L2 = finds(vs[j]);           //找到两个嫌疑人的父亲节点,并且让较小的值为根节点
                if(L1 != L2)
                {
                    if(L1 < L2) swap(L1, L2);
                    parents[L1] = L2;//小的编号作为leader
                }
            }
        }
    }

    map<int, vector<int>> mp;   //mp统计最后的结果
    
    for(int i = 0; i < sz; i++)
    {
        int L = finds(vs[i]);
        mp[L].push_back(vs[i]);
    }
    
    
    if(mp.size() == 0)
    {
        printf("None\n");
        return 0;
    }
    for(auto x: mp)
    {
        sort(x.second.begin(), x.second.end());//gang内排序
        int kk = x.second.size();
        for(int i = 0; i < kk; ++i)
        {
            printf("%d%c", x.second[i], i == kk - 1? '\n': ' ');
        }
    }
    return 0;
}


7-4 Structure of a Binary Tree


#include<bits/stdc++.h>
using namespace std;

const int maxn=33;

int post[maxn],in[maxn];

unordered_map<int,int> L,R,p,pos,depth;

int n;

int build(int il,int ir,int postl,int postr,int level)
{
    int root=post[postr];
    int k=pos[root];

    if(il<k)
    {
            L[root]=build(il,k-1,postl,postl+k-il-1,level+1);
            p[L[root]]=root;
    }

    if(k<ir)
    {
        R[root]=build(k+1,ir,postl+k-il,postr-1,level+1);
        p[R[root]]=root;
    }
    depth[root]=level;
    return root;
}

bool is_fulltree(int u)
{
    int cnt_child=0;
    bool flag=true;

    if(L.count(u))
    {
        cnt_child++;
        flag=flag&is_fulltree(L[u]);
    }

    if(R.count(u))
    {
        cnt_child++;
        flag=flag&is_fulltree(R[u]);
    }
    return flag && (cnt_child==2 || !cnt_child);
}

int main()
{
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> post[i];
    for(int i=0; i<n; i++)
    {
        cin >> in[i];
        pos[in[i]]=i;
    }

    int root=build(0,n-1,0,n-1,0);

    int k;
    cin >> k;
    getchar();
    string str;
    while(k--)
    {
        bool flag=true;
        getline(cin,str);
        stringstream ssin(str);
        if(str.substr(str.size()-4)=="root")
        {
            int a;
            ssin >> a;
            flag=a==root;
        }
        else if(str.substr(str.size()-5)=="level")
        {
            int a,b;
            ssin >> a;
            while(ssin>>str && !isdigit(str[0]))
                ;
            b=stoi(str);
            if(!depth.count(a) || !depth.count(b))
                flag=false;
            else
                flag=depth[a]==depth[b];
        }
        else if(str.substr(str.size()-4)=="tree")
        {
            flag=is_fulltree(root);
        }
        else if(str.substr(str.size()-8)=="siblings")
        {
            int a,b;
            ssin >> a;
            while(ssin>>str && !isdigit(str[0]))
                ;
            b=stoi(str);
            if(!p.count(a) || !p.count(b))
                flag=false;
            else
                flag=p[a]==p[b];
        }
        else
        {
            int a,b;
            ssin >> a;
            for(int i=0; i<3; i++)
                ssin >> str;
            if(str=="parent")
            {
                while(ssin>>str && !isdigit(str[0]))
                    ;
                b=stoi(str);
                if(!p.count(b))
                    flag=false;
                else
                    flag=p[b]==a;
            }
            else if(str=="left")
            {
                while(ssin>>str && !isdigit(str[0]))
                    ;
                b=stoi(str);
                if(!L.count(b))
                    flag=false;
                else
                    flag=L[b]==a;
            }
            else
            {
                while(ssin>>str && !isdigit(str[0]))
                    ;
                b=stoi(str);
                if(!R.count(b))
                    flag=false;
                else
                    flag=R[b]==a;
            }
        }
        if(flag)
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
    return 0;
}

7-1sex prime


#include<bits/stdc++.h>
using namespace std;

int n;

bool isprime(int x)
{
    if(x<=1)
        return false;
    for(int i=2; i*i<=x; i++)
        if(x%i==0)
            return false;
    return true;
}

int main()
{
    cin >> n;
    if(isprime(n) && isprime(n-6))
    {
        cout << "Yes" << endl;
        cout << n-6;
    }
    else if(isprime(n) && isprime(n+6))
    {
        cout << "Yes" << endl;
        cout << n+6;
    }
    else
    {
        cout << "No" << endl;
        while(1)
        {
            n++;
            if(isprime(n) && isprime(n-6) && n>=6)
            {
                cout << n;
                break;
            }
            else if(isprime(n) && isprime(n+6) && n>=6)
            {
                cout << n;
                break;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值