PAT甲级2019春季真题题解

PAT甲级2019春季题目及满分代码下载

A Sexy Primes

在这里插入图片描述
  签到题,素数不需要用筛法,直接O(sqrt(n))即可。

#include<iostream>

using namespace std;

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

int main() {
    
    
    int n;

    cin >> n;

    if (check(n - 6) && check(n)) {
    
    
        cout << "Yes" << endl << n - 6;
    } else if (check(n) && check(n + 6)) {
    
    
        cout << "Yes" << endl << n + 6;
    } else {
    
    
        cout << "No" << endl;
        for (int i = n + 1;; i++) {
    
    
        	//注意
            if (check(i) && (check(i - 6) || check(i + 6))) {
    
    
                cout << i;
                break;
            }
        }
    }

    return 0;
}

B Anniversary

在这里插入图片描述
  热身题,字符串处理,使用集合判断。

#include<iostream>
#include<unordered_set>
#include<string>

#define ac cin.tie(0);cin.sync_with_stdio(0);

using namespace std;
unordered_set<string> set;

int main() {
    
    
    ac
    int n, cnt = 0;
    string s, old_al = "99999999999999999999999999999", ans = "9999999999999999999999999999999";

    cin >> n;
    while (n--) {
    
    
        cin >> s;
        set.insert(s);
        //记录最老的校友,出生年份越小越老
        if (s.substr(6, 8) < old_al.substr(6, 8))
            old_al = s;
    }

    cin >> n;
    while (n--) {
    
    
        cin >> s;
        if (set.count(s)) 
            ++cnt;
        ///记录最老的来宾
        if (s.substr(6, 8) < ans.substr(6, 8))
            ans = s;
    }
    cout << cnt << endl;
    if (cnt) {
    
    
        cout << old_al;
    } else {
    
    
        cout << ans;
    }
    return 0;
}

C Telefraud Detection

在这里插入图片描述
  稍难,图论+并查集,还有要理解题意(个人认为PAT最难的点)。

#include<iostream>
#include<vector>
#include<algorithm>

#define ac cin.tie(0);cin.sync_with_stdio(0);

using namespace std;
const int MAXN = 1010;
int G[MAXN][MAXN], pre[MAXN];
bool vis[MAXN];
vector<int> v;
int n, m, k;

int find(int a) {
    
    
    return pre[a] == a ? a : pre[a] = find(pre[a]);
}

int main() {
    
    
    ac
    int a, b, c;

    cin >> k >> n >> m;
    while (m--) {
    
    
        cin >> a >> b >> c;
        G[a][b] += c;
    }

    for (int i = 1; i <= n; i++) {
    
    
        int cnt = 0, bt = 0;
        for (int j = 1; j <= n; j++) {
    
    
            //短通话有效
            if (G[i][j] && G[i][j] <= 5) {
    
    
                ++cnt;
                //记录回电次数
                if (G[j][i])
                    ++bt;
            }
        }
        //可疑诈骗电话加入v
        if (cnt > k && bt * 5 <= cnt)
            v.push_back(i);
    }

    //没有可疑人员
    if (!v.size()) {
    
    
        cout << "None";
        return 0;
    }
    //准备并查集
    for (int i:v)
        pre[i] = i;

    for (int i = 0; i < v.size(); i++) {
    
    
        for (int j = i + 1; j < v.size(); j++) {
    
    
            //双方都有通话
            if (G[v[j]][v[i]] && G[v[i]][v[j]]) {
    
    
                int a = find(v[j]);
                int b = find(v[i]);
                pre[a] = b;
            }
        }
    }

    for (int i = 0; i < v.size(); i++) {
    
    
        if (vis[v[i]])
            continue;
        if (i)
            cout << endl;
        vector<int> tmp;
        tmp.push_back(v[i]);
        int a = find(v[i]);
        //查找同伙
        for (int j = i + 1; j < v.size(); j++)
            if (find(v[j]) == a) {
    
    
                vis[v[j]] = true;
                tmp.push_back(v[j]);
            }
        for (int j = 0; j < tmp.size(); j++) {
    
    
            if (j)
                cout << " ";
            cout << tmp[j];
        }
    }
    return 0;
}

D Structure of a Binary Tree

在这里插入图片描述
  要细心,做对不容易,建树、DFS,处理每个输入。(PS. 满二叉树的定义有歧义。)

#include<iostream>
#include<string>

using namespace std;
const int MAXN = 1010;
int post[MAXN], in[MAXN];
int le[MAXN], ri[MAXN], map[MAXN], dep[MAXN];
int n, m, k;
//建树
int buildTree(int a, int b) {
    
    
    if (a > b)
        return -1;

    int pos = map[post[k]];
    --k;
    ri[in[pos]] = buildTree(pos + 1, b);
    le[in[pos]] = buildTree(a, pos - 1);
    return in[pos];
}
//确定是否为满二叉树并且确定节点的层次
void dfs(int root, bool &op, int t) {
    
    
    if (root == -1)
        return;

    int tt = 0;
    if (le[root] == -1)++tt;
    if (ri[root] == -1)++tt;

    if (tt & 1)
        op = false;
    dep[root] = t;
    dfs(le[root], op, t + 1);
    dfs(ri[root], op, t + 1);
}

int main() {
    
    
    string s;

    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> post[i];
    for (int i = 0; i < n; i++) {
    
    
        cin >> in[i];
        map[in[i]] = i;
    }
    k = n - 1;
    int root = buildTree(0, n - 1);


    //判断是否为满二叉树
    //是否为满二叉树
    bool op = true;
    dfs(root, op, 0);

    cin >> m;
    getchar();
    while (m--) {
    
    
        getline(cin, s);
        bool ans = false;

        if (s == "It is a full tree") {
    
    
            if (op)
                ans = true;
        } else if (s[s.length() - 1] == 't') {
    
    
            int a;
            sscanf(s.c_str(), "%d is the root", &a);
            if (a == root)
                ans = true;
        } else if (s[s.length() - 1] == 's') {
    
    
            int a, b;
            sscanf(s.c_str(), "%d and %d are siblings", &a, &b);
            for (int i = 0; i < n; i++)
                if ((le[in[i]] == a && ri[in[i]] == b) || (le[in[i]] == b && ri[in[i]] == a)) {
    
    
                    ans = true;
                    break;
                }
        } else if (s.find("parent") != string::npos) {
    
    
            int a, b;
            sscanf(s.c_str(), "%d is the parent of %d", &a, &b);
            if (le[a] == b || ri[a] == b)
                ans = true;
        } else if (s.find("left") != string::npos) {
    
    
            int a, b;
            sscanf(s.c_str(), "%d is the left child of %d", &a, &b);
            if (le[b] == a)
                ans = true;
        } else if (s.find("right") != string::npos) {
    
    
            int a, b;
            sscanf(s.c_str(), "%d is the right child of %d", &a, &b);
            if (ri[b] == a)
                ans = true;
        } else {
    
    
            int a, b;
            sscanf(s.c_str(), "%d and %d are on the same level", &a, &b);
            if (dep[a] == dep[b])
                ans = true;
        }

        if (ans)
            cout << "Yes";
        else
            cout << "No";
        if (m)
            cout << endl;
    }

    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Raymond_YP/article/details/110589944