1. 程式人生 > 實用技巧 >Codeforces Global Round 12(個人題解)

Codeforces Global Round 12(個人題解)

1450A. Avoid Trygub

挺簡單的題,題意是避免字串中有子串“Trygub"

只要給字串排序就可以了,這樣一定不會出現

void solve() {
    string s; int n;
    cin >> n >> s;
    sort(s.begin(), s.end());
    cout << s << endl;
}

1450B. Balls of Steel

想太多了,因為資料範圍比較小,可以直接暴力比較一下就ok

void solve() {
    int n, k;
    cin >> n >> k;
    int x[n], y[n];
    for (int i = 0; i < n; ++i)
        cin >> x[i] >> y[i];
    bool fl = true;
    for (int i = 0; i < n && fl; i++) {
        fl = 0;
        for (int j = 0; j < n; j++)
            if (abs(x[i] - x[j]) + abs(y[i] - y[j]) > k)
                fl = 1;
    }
    cout << (fl ? -1 : 1) << endl;
}

1450C1&C2. Errich-Tac-Toe (Hard Version)

剛開始看的時候有點懵,看了一下洛凌璃dalao的解釋明白了。

考慮(i + j) % 3, 記 ++cnt[(i + j) % 3][s[i][j] == 'X']

最後無非選擇 i, j(-1<i,j<3, i!=j) 使得 s[i][1] + s[j][0] <= k/3, 即使得每3個相鄰的標記中存在兩個不同的標記

一定存在這樣的 i, j使得 <= k/3, 自己畫個表就明白了

int _, n, m, s[2][5];
char a[305][305];
void solve() {
    int i, j, k, t;
    scanf("%d", &n);
    m = 0;
    memset(s, 0, sizeof(s));
    for (i = 0; i < n; i++) {
        scanf("%s", a[i]);
        for (j = 0; j < n; j++)
            if (a[i][j] != '.')
                m++, s[a[i][j] == 'X'][(i + j) % 3]++;
    }
    for (k = 0; k < 3; k++)
        for (t = 0; t < 3; t++)
            if (k ^ t && s[1][k] + s[0][t] <= m / 3) {
                for (i = 0; i < n; i++)
                    for (j = 0; j < n; j++)
                        if (a[i][j] != '.')
                            if ((i + j) % 3 == k)
                                a[i][j] = 'O';
                            else if ((i + j) % 3 == t)
                                a[i][j] = 'X';
                m = -3;
            }
    for (i = 0; i < n; i++)
        printf("%s\n", a[i]);
}

1450D. Rating Compression

根據題意模擬一下,各個使用者滿意情況

const int N = 3e5 + 10;
char s[N];
vector<int> v[N];
void solve() {
    int n, a, i, j;
    i = 0;
    // 把各位數字的出現次數標記
    for (cin >> n; i != n; s[i++] = '0', cin >> a, v[a].push_back(i))
        ;
   	// 模擬條件
    for (a = j = 1; v[a].size() == 1 && (j == v[a][0] || v[a][0] == i);
         s[n - a] = '1', i == v[a++][0] ? --i : ++j)
        ;
    for (v[a].empty() ? '0' : s[n - a] = '1'; a <= n && v[a].size() == 1; ++a)
        ;
    // 設定'\0',並且重置v陣列
    for (s[n] = 0, a == ++n ? s[0] = '1' : '0'; --n; v[n].clear())
        ;
    cout << s << endl;
}

1450E. Capitalism

建圖跑個多源floyd最短路就好,

順便記得判個負環

// Author : RioTian
// Time : 20/12/21
#include <bits/stdc++.h>
using namespace std;
#define all(s) (s.being(), s.end())
#define rep(i, s, n) for (int i = s; i <= n; ++i)
typedef long long ll;
int n, m, g[200][200];
int a[2000], b[2000], c;

int main(void) {
    memset(g, 0x3f, sizeof(g));
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &a[i], &b[i], &c);
        g[a[i] - 1][b[i] - 1] = 1;
        if (c == 1)
            g[b[i] - 1][a[i] - 1] = -1;
        else
            g[b[i] - 1][a[i] - 1] = 1;
    }
    for (int i = 0; i < n; i++)
        g[i][i] = 0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            for (int k = 0; k < n; k++)
                g[j][k] = min(g[j][k], g[j][i] + g[i][k]);
    int pos = -1, ans = -1;
    for (int i = 0; i < n; i++) {
        if (g[i][i] < 0) {
            printf("NO\n");
            return 0;
        }
        int mx = -n, mn = n;
        for (int j = 0; j < n; j++) {
            mx = max(mx, g[i][j]);
            mn = min(mn, g[i][j]);
        }
        for (int j = 0; j < m; j++)
            if (g[i][a[j] - 1] == g[i][b[j] - 1])
                mx = -n;
        if (ans < mx - mn) {
            ans = mx - mn;
            pos = i;
        }
    }
    if (ans == -1)
        printf("NO\n");
    else {
        printf("YES\n%d\n", ans);
        for (int i = 0; i < n; i++)
            printf("%d%c", g[pos][i] + n, i == n - 1 ? '\n' : ' ');
    }
    return 0;
}

F、G、F1&F2沒做出來了。等待以後重新補題