AtCoder Beginner Contest 287(5/8)

Majority

模拟

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    int sum = 0;
    for (int i = 0; i < n; i++) {
        string s;
        cin >> s;
        if (s == "For") {
            sum++;
        }
    }
    if (sum >= (n + 1) / 2) {
        cout << "Yes\n";
    } else {
        cout << "No\n";
    }
    return 0;
}

Postal Card

暴力,模拟

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<string> a(n), b(m);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < m; i++) {
        cin >> b[i];
    }
    int ans = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            bool ok = true;
            for (int k = 0; k < 3; k++) {
                if (a[i][k + 3] != b[j][k]) {
                    ok = false;
                    break;
                }
            }
            if (ok) {
                ans++;
                break;
            }
        }
    }
    cout << ans << '\n';
    return 0;
}

Path Graph?

要想构成path graph,边的个数必须是n-1,但n-1条边的图不一定是path graph,也可能是一棵树,所以就从度为1的点dfs,判断有没有度大于2的点,并且能否遍历所有点

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<vector<int>> G(n + 1);
    vector<int> a(n + 1);
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
        a[u]++;
        a[v]++;
    }
    int root = -1;
    for (int i = 1; i <= n; i++) {
        if (a[i] == 1) {
            root = i;
            break;
        }
    }
    if (root == -1) {
        cout << "No\n";
        return 0;
    }
    vector<bool> vis(n + 1);
    function<void(int, int)> dfs = [&](int u, int fa) {
        vis[u] = true;
        if (G[u].size() >= 3) {
            return;
        }
        for (auto v : G[u]) {
            if (v != fa) {
                dfs(v, u);
            }
        }
    };
    dfs(root, 0);
    bool ok = true;
    for (int i = 1; i <= n; i++) {
        if (!vis[i]) {
            ok = false;
            break;
        }
    }
    if (ok) {
        cout << "Yes\n";
    } else {
        cout << "No\n";
    }
    return 0;
}

Match or Not

操作是取字符串s的前x个字符和后|t|-x个字符拼接成长度为|t|的字符串,然后和字符串t比较能否匹配,不难看出,一开始由s得到的字符串是s的最后|t|个字符组成的字符串,然后每次操作就把这长度为|t|的字符串的前x个字符替换成s的第x个字符,因此,只需要从一开始判断有没有不匹配的地方,并记录下来,只要有一个地方一直不匹配,就一直输出No,某次操作后所有都匹配了,才输出Yes

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    string s, t;
    cin >> s >> t;
    int len = s.size(), len1 = t.size();
    string now = "";
    for (int i = len - 1; i >= len - len1; i--) {
        now += s[i];
    }
    reverse(now.begin(), now.end());
    set<int> se;
    for (int i = 0; i < len1; i++) {
        if (now[i] == '?') {
            continue;
        }
        if (t[i] == '?') {
            continue;
        }
        if (now[i] != t[i]) {
            se.insert(i);
        }
    }
    bool ok;
    int p;
    if (se.size() == 0) {
        cout << "Yes\n";
        ok = true;
    } else {
        ok = false;
        p = *se.begin();
        cout << "No\n";
    }
    for (int i = 1, j = 0; i <= len1; i++, j++) {
        now[j] = s[i - 1];
        if (se.size() > 0) {
            p = *se.begin();
        }
        if (now[j] == '?') {
            if (p == i - 1 && se.size()) {
                se.erase(p);
            }
        } else if (t[i - 1] == '?') {
            if (p == i - 1 && se.size()) {
                se.erase(p);
            }
        } else if (t[i - 1] == now[j]) {
            if (p == i - 1 && se.size()) {
                se.erase(p);
            }
        } else {
            se.insert(i - 1);
        }
        if (se.size()) {
            cout << "No\n";
        } else {
            cout << "Yes\n";
        }
    }
    return 0;
}

Karuta

字典树

题意是找与当前字符串有着共同前缀,前缀的最大长度

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int son[500010][26], cnt[500010][26], idx;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<string> a(n);
    function<void(string)> insert = [&](string s) {
        int p = 0, len = s.size();
        for (int i = 0; i < len; i++) {
            int u = s[i] - 'a';
            cnt[p][u]++;
            if (!son[p][u]) {
                son[p][u] = ++idx;
            }
            p = son[p][u];
        }
    };
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        insert(a[i]);
    }
    function<int(string)> query = [&](string s) {
        int p = 0, len = s.size();
        for (int i = 0; i < len; i++) {
            int u = s[i] - 'a';
            if (cnt[p][u] < 2) {
                return i;
            }
            p = son[p][u];
        }
        return len;
    };
    for (int i = 0; i < n; i++) {
        cout << query(a[i]) << '\n';
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值