PAT甲级2018冬季真题题解

A Google Recruitment

  热身题,素数,stoll函数,注意数据范围。

#include<iostream>
#include<string>

using namespace std;

bool check(const string &s) {
    
    
    long long tmp = stoll(s);
    if (tmp < 2)
        return false;
    for (int i = 2; (long long) i * i <= tmp; i++)
        if (tmp % i == 0)
            return false;
    return true;
}

int main() {
    
    
    int l, k;
    string s;

    cin >> l >> k;
    cin >> s;
    //这里要取等号
    for (int i = 0; i + k <= s.length(); i++) {
    
    
        string tmp = s.substr(i, k);
        if (check(tmp)) {
    
    
            cout << tmp;
            return 0;
        }
    }
    cout << "404";
    return 0;
}

B Decode Registration Card of PAT

  复杂的字符串题,需要细心,频繁输入输出的情况下使用scanf printf,这题使用cin cout最后一个样例TLE。

//高"IO"使用scanf
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<algorithm>

using namespace std;
const int MAXN = 10010;

struct node {
    
    
    string id;
    int score;

    node() {
    
    };

    node(string a, int b) : id(a), score(b) {
    
    };
	//排序
    bool operator<(const node &a) {
    
    
        if (score != a.score)
            return score > a.score;
        else
            return id < a.id;
    }
} arr[MAXN];

int main() {
    
    
    int n, m;
    int tp;
    string s;

    cin >> n >> m;
    for (int i = 0; i < n; i++)
        cin >> arr[i].id >> arr[i].score;

    for (int i = 1; i <= m; i++) {
    
    
        cin >> tp >> s;
        printf("Case %d: %d %s\n", i, tp, s.c_str());
        if (tp == 1) {
    
    
            vector<node> ans;
            for (int i = 0; i < n; i++)
            	//匹配考试等级
                if (arr[i].id[0] == s[0])
                    ans.push_back(arr[i]);
            if (!ans.size()) {
    
    
                printf("NA\n");
                continue;
            }
            sort(ans.begin(), ans.end());
            for (const node &a:ans)
                printf("%s %d\n", a.id.c_str(), a.score);
        } else if (tp == 2) {
    
    
            int cnt = 0, res = 0;
            for (int i = 0; i < n; i++)
            	//匹配考场号
                if (arr[i].id.substr(1, 3) == s) {
    
    
                    ++cnt;
                    res += arr[i].score;
                }
            if (!cnt) {
    
    
                printf("NA\n");
                continue;
            }
            printf("%d %d\n", cnt, res);
        } else {
    
    
            unordered_map<string, int> map;
            for (int i = 0; i < n; i++) {
    
    
                string tmp = arr[i].id.substr(1, 3);
                //匹配日期,但是要对考场号处理
                if (arr[i].id.substr(4, 6) == s) {
    
    
                    if (map.find(tmp) == map.end()) {
    
    
                        map[tmp] = 0;
                    }
                    map[tmp]++;
                }
            }
            vector<node> ans;
            for (auto i:map) {
    
    
                ans.push_back(node(i.first, i.second));
            }
            if (!ans.size()) {
    
    
                printf("NA\n");
                continue;
            }
            sort(ans.begin(), ans.end());
            for (const node &a:ans)
                printf("%s %d\n", a.id.c_str(), a.score);
        }
    }

    return 0;
}

C Vertex Coloring

  简单图论,邻接表存边,然后按照题意编程即可。

//邻接表存储,否则TLE
#include<iostream>
#include<vector>
#include<unordered_set>
#include<algorithm>

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

using namespace std;
const int MAXN = 10010;
vector<int> G[MAXN];
int arr[MAXN];
int n, m, k;

int main() {
    
    
    ac
    int a, b;

    cin >> n >> m;
    while (m--) {
    
    
        cin >> a >> b;
        //无向图,但是只需要存储"半条边",因为遍历的时候从0-n
        if (a > b)
            swap(a, b);
        G[a].push_back(b);
    }

    cin >> k;
    while (k--) {
    
    
        bool op = true;
        //记录颜色数
        unordered_set<int> set;

        for (int i = 0; i < n; i++)
            cin >> arr[i];

        for (int i = 0; i < n; i++) {
    
    
            set.insert(arr[i]);
            for (int j:G[i])
            	//邻接又颜色相等,不符合题意
                if (arr[i] == arr[j]) {
    
    
                    op = false;
                    break;
                }
        }
        if (op)
            cout << set.size() << "-coloring";
        else
            cout << "No";
        if (k)
            cout << endl;
    }
    return 0;
}

D Heap Paths

  中等难度的树题,如果不是完全二叉树就有难度了,DFS。

#include<cstdio>
#include<vector>

using namespace std;
const int MAXN = 1010;
int arr[MAXN];
vector<int> path;
int n;
bool op1 = true, op2 = true;

void dfs(int root, int fa) {
    
    
    if (fa != -1) {
    
    
    	//子节点比父结点大,不可能是大根堆
        if (arr[root] > arr[fa])
            op1 = false;
        //子节点比父结点小,不可能是小根堆
        if (arr[root] < arr[fa])
            op2 = false;
    }
	//加入path
    path.push_back(arr[root]);
    if (2 * root > n) {
    
    
        for (int i = 0; i < path.size(); i++) {
    
    
            if (i)
                printf(" ");
            printf("%d", path[i]);
        }
        printf("\n");
        //回溯 pop
        path.pop_back();
        return;
    }
    //先遍历右子树,完全二叉树右儿子为2*root+1
    if (2 * root + 1 <= n)
        dfs(2 * root + 1, root);
    //再遍历左子树,完全二叉树左儿子为2*root
    dfs(2 * root, root);
    //回溯pop
    path.pop_back();
}

int main() {
    
    
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &arr[i]);

    dfs(1, -1);
    if (op1)
        printf("Max Heap");
    else if (op2)
        printf("Min Heap");
    else
        printf("Not Heap");
    return 0;
}

PS.明天PAT冬季赛,冲冲冲!!!

猜你喜欢

转载自blog.csdn.net/Raymond_YP/article/details/110671658
今日推荐