PTA甲 1164~1167题解

1164 Good in C

挺无聊的模拟,要按行读并切片,并切片。

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

static string let[26][7];

int main()
{
    for (auto & i : let) {
        for (auto & j : i) {
            cin >> j;
        }
    }

    char _ = getchar();
    string s;
    getline(cin, s);
    for (char& c : s) {
        if (c >= 'A' && c <= 'Z') continue;
        else c = ' ';
    }
    stringstream ss(s);

    vector<string> res;
    while (ss >> s) res.push_back(s);

    int n{int(res.size())};
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 7; j++) {
            for (int k = 0; k < res[i].size(); k++) {
                if (k ^ 0) cout << ' ';
                cout << let[res[i][k] - 'A'][j];
            }
            cout << '\n';
        }
        if (i ^ n - 1) cout << '\n';
    }

    return 0;
}

1165 Block Reversing

翻转,但相对顺序没变。有个1分的样例是有没用的节点。

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

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string head;
    int N, K;
    cin >> head >> N >> K;

    unordered_map<string, string> nex, data;
    for (int i = 0; i < N; i++) {
        string add, dat, ne;
        cin >> add >> dat >> ne;
        nex[add] = ne;
        data[add] = dat;
    }

    vector<string> v, res;
    while (head != "-1") {
        v.push_back(head);
        head = nex[head];
    }
    N = v.size();
    // assert(v.size() == N);

    int last = K == 0 ? 0 : N % K;
    for (int i = N - last; i < N; i++) res.push_back(v[i]);

    for (int i = N - last - K; i >= 0; i -= K) {
        for (int j = 0; j < K; j++) res.push_back(v[i + j]);
    }

    for (int i = 0; i < N - 1; i++) {
        cout << res[i] << ' ' << data[res[i]] << ' ' << res[i + 1] << '\n';
    }
    cout << res.back() << ' ' << data[res.back()] << ' ' << -1 << '\n';

    return 0;
}

1166 Summit

跟1070没啥区别。需要朋友就是这个L个邻接表的交集,除了这L个人之外还有人;需要帮助就是二重循环暴力枚举;除此之外就是OK了。

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

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, K; cin >> N >> K;
    vector<unordered_set<int>> graph(N + 1);
    while (K--) {
        int a, b; cin >> a >> b;
        graph[a].insert(b);
        graph[b].insert(a);
    }

    cin >> K;
    for (int A = 1; A <= K; A++) {
        int t; cin >> t;
        vector<int> v(t);
        for (int i = 0; i < t; i++) cin >> v[i];

        bool ok = false;
        for (int i = 0; i < t; i++) {
            for (int j = i + 1; j < t; j++) {
                if (!graph[v[i]].count(v[j])) {
                    cout << "Area " << A << " needs help.\n";
                    ok = true;
                    break;
                }
            }
            if (ok) break;
        }

        if (!ok) {
            map<int, int> sec;
            for (int x : v) {
                for (int y : graph[x]) sec[y]++;
            }
            for (int x : v) sec.erase(x);
            for (const auto& [a, b] : sec) {
                if (b == t) {
                    cout << "Area " << A << " may invite more people, such as " << a << ".\n";
                    ok = true;
                    break;
                }
            }
        }

        if (!ok) cout << "Area " << A << " is OK.\n";
    }

    return 0;
}

1167 Cartesian Tree

重建二叉树是很类似的。
中序遍历 也就是 左根右
而这里的根是min-heap,所以也就是[L, R]的区间最小值。
递归建树 然后bfs输出

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

class TreeNode {
public:
    explicit TreeNode(int v):
             val(v), left(nullptr), right(nullptr) {}
public:
    TreeNode *left;
    TreeNode *right;
    int val;
};

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

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

    function<TreeNode*(int, int)> build = [&](int l, int r) -> TreeNode* {
        if (l > r) return nullptr;
        if (l == r)
            return new TreeNode(v[l]);

        int idx, mi = INT_MAX;
        for (int i = l; i <= r; i++) {
            if (v[i] < mi) {
                mi = v[i];
                idx = i;
            }
        }

        auto* root = new TreeNode(mi);
        root->left = build(l, idx - 1);
        root->right = build(idx + 1, r);
        return root;
    };

    auto* root = build(0, n - 1);

    vector<int> res;
    queue<TreeNode*> qu;
    qu.push(root);
    while (!qu.empty()) {
        auto sz = qu.size();
        while (sz--) {
            auto f = qu.front();
            res.push_back(f->val);
            if (f->left) qu.push(f->left);
            if (f->right) qu.push(f->right);
            qu.pop();
        }
    }
    for (int i = 0; i <res.size(); i++) {
        if (i ^ 0) cout << ' ';
        cout << res[i];
    }
    cout << '\n';

    return 0;
}

总结

怎么近来的PTA甲都很无趣了呢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值