SMU Spring 2023 Trial Contest Round 9

A. Wrong Subtraction

#include <bits/stdc++.h>

using namespace std;

int32_t main() {
    int n, k;
    cin >> n >> k;
    while (k--) {
        if (n % 10 == 0) n /= 10;
        else n--;
    }
    cout << n;
    return 0;
}

B. Two-gram

#include <bits/stdc++.h>

using namespace std;

int32_t main() {
    int n;
    cin >> n;
    string s;
    cin >> s;
    map<string, int> cnt;
    for (int i = 0; i + 1 < n; i++)
        cnt[s.substr(i, 2)]++;
    int val = 0;
    string res = "";
    for (auto [k, v]: cnt) {
        if (v > val) val = v, res = k;
    }
    cout << res << "\n";
    return 0;
}

C. Less or Equal

排序,如果第\(k\) 大和第\(k+1\)大不同输出第\(k\)大,否则输出\(-1\)

特判\(k=0,k=n\)

#include <bits/stdc++.h>

using namespace std;


int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

int32_t main() {
    int n = read(), k = read();
    vector<int> a(n);
    for (auto &i: a) i = read();
    sort(a.begin(), a.end());
    if (k == 0) {
        if (a[0] == 1) cout << "-1";
        else cout << "1";
    } else if (k == n) cout << a.back();
    else {
        if (a[k] == a[k - 1]) cout << "-1";
        else cout << a[k - 1] << "\n";
    }
    return 0;
}

D. Divide by three, multiply by two

建图跑搜索即可。复杂度\(O(\frac{n^2}{4})\)

#include <bits/stdc++.h>

using namespace std;

#define int long long

int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

int n;
vector<vector<int>> e;
vector<int> res, a;
vector<bool> vis;

void dfs(int x) {
    if (res.size() == n) {
        for (auto i: res) printf("%lld ", a[i]);
        exit(0);
    }
    for (auto v: e[x]) {
        if (vis[v]) continue;
        vis[v] = true, res.push_back(v);
        dfs(v);
        vis[v] = false, res.pop_back();
    }
    return;
}

int32_t main() {
    n = read();
    a = vector<int>(n + 1);
    e = vector<vector<int>>(n + 1);
    vis = vector<bool>(n + 1, false);
    for (int i = 1; i <= n; i++) a[i] = read(), e[0].push_back(i);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j < i; j++) {
            if (a[i] * 2 == a[j]) e[i].push_back(j);
            if (a[i] * 3 == a[j]) e[j].push_back(i);
            if (a[j] * 2 == a[i]) e[j].push_back(i);
            if (a[j] * 3 == a[i]) e[i].push_back(j);
        }
    dfs(0);
    return 0;
}

E. Cyclic Components

并查集判断连通性,联通块内每个点的度数都是 2 的即为题面要求的环

#include <bits/stdc++.h>

using namespace std;

#define int long long

int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

struct dsu {
    vector<int> fa;

    dsu(int n = 0) {
        fa = vector<int>(n + 1, -1);
    }

    int getfa(int x) {
        if (fa[x] < 0) return x;
        return fa[x] = getfa(fa[x]);
    }

    bool merage(int x, int y) {
        x = getfa(x), y = getfa(y);
        if (x == y) return false;
        if (fa[x] > fa[y]) swap(x, y);
        fa[x] += fa[y], fa[y] = x;
        return true;
    }

    bool check(int x, int y) {
        x = getfa(x), y = getfa(y);
        return x == y;
    }
};

int32_t main() {
    int n = read();
    vector<int> d(n + 1);
    dsu D(n);
    for (int x, y, m = read(); m; m--) {
        x = read(), y = read(), d[x]++, d[y]++;
        D.merage(x, y);
    }
    int res = 0;
    map<int, vector<int>> t;
    for (int i = 1; i <= n; i++) t[D.getfa(i)].push_back(i);
    for (auto it: t) {
        int f = 1;
        for (auto i: it.second)
            if (d[i] != 2) {
                f = 0;
                break;
            }
        res += f;
    }
    cout << res;
    return 0;
}

F. Consecutive Subsequence

首先\(O(n)\)的 dp 求最长连续子序列的长度和最后一个数。然后就可以还原出子序列中每个数的值,贪心的从后先前选择可选的最大值即可。

#include <bits/stdc++.h>

using namespace std;


int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

int32_t main() {
    int n = read();
    map<int, int> f;
    map<int,vector<int>> cnt;
    for (int x , i = 1 ; i <= n; i ++ )
        x = read(), f[x] = max(1, f[x - 1] + 1) , cnt[x].push_back(i);
    int res = 0 , t ;
    for( auto [ k , v ] : f ){
        if( v > res ) res = v , t = k;
    }
    cout << res << "\n";
    vector<int> ans;
    for( int i = res , p = INT_MAX ; i ; i -- , t -- ){
        while( cnt[t].back() >= p ) cnt[t].pop_back();
        ans.push_back( cnt[t].back() ) , p = cnt[t].back();
    }
    reverse(ans.begin(), ans.end());
    for( auto i : ans ) cout << i << " ";

    return 0;
}
posted @ 2023-04-23 16:03  PHarr  阅读(23)  评论(0编辑  收藏  举报