Educational Codeforces Round 116 (Rated for Div. 2) problem solving Report

A - AB Balance

meaning of the title

Give a string \ (s \) only composed of characters \ (a \) and \ (b \), and find the least modification to make the occurrence times of \ (ab \) in \ (s \) equal to that of \ (ba \).

thinking

\In (s \), both \ (ab \) and \ (ba \) only appear between consecutive segments and appear alternately, so the maximum difference in the number of occurrences is \ (1 \). If there are odd segments, the occurrence times of them must be equal; If there are even segments, only the first character needs to be modified, and it will become odd segments.

Therefore, the first character can be modified as long as the occurrence times are not equal.

code

#include<cstdio>
#include<cstring>
using namespace std;

const int MAXN = 100 + 5;

char s[MAXN];
int n;

int main() {
    int T;

    scanf("%d", &T);
    while(T--) {
        scanf("%s", s + 1);
        n = strlen(s + 1);
        int cntAB = 0, cntBA = 0;
        for(int i = 1; i <= n - 1; i++) {
            if(s[i] == 'a' && s[i + 1] == 'b') {
                cntAB++;
            }
            if(s[i] == 'b' && s[i + 1] == 'a') {
                cntBA++;
            }
        }
        if(cntAB != cntBA) {
            if(s[1] == 'a') {
                s[1] = 'b';
            } else {
                s[1] = 'a';
            }
        }
        printf("%s\n", s + 1);
    }

    return 0;
}

B - Update Files

meaning of the title

There are \ (n \) computers and \ (k \) data lines. Each data line can only connect two computers at the same time. Ask how many rounds it takes to transfer the files on the \ (1 \) computer to all \ (n \) computers.

thinking

When the total number of computers with files is less than \ (K \), the total number of computers transmitting files will obviously double each time, i.e. \ (1 \), \ (2 \), \ (4 \), \ (8 \), \ (16 \)... But if the total number of computers with files exceeds \ (K \), only \ (K \) can be added each time. The final result is \ (\ lceil \frac{n - 2^m}{k} \rceil + m\) (\(2^m \leq n \) and \ (2 ^ m > k \), \ (2 ^ {m - 1}) \leq k\)).

code

#include<cstdio>
using namespace std;

long long n, k;

int main() {
    int T;

    scanf("%d", &T);
    while(T--) {
        scanf("%lld%lld", &n, &k);
        if(n == 1) {
            printf("0\n");
            continue;
        }
        if(k == 1) {
            printf("%lld\n", n - 1);
            continue;
        }
        long long b = 1, cnt = 0;
        while(b <= k && b * 2 <= n) {
            b *= 2;
            cnt++;
        }
        cnt += (n - b) / k;
        if((n - b) % k != 0) {
            cnt++;
        }
        printf("%lld\n", cnt);
    }

    return 0;
}

C - Banknotes

meaning of the title

Give \ (n \) banknotes with a face value of \ (10^{a_i} \), and find the minimum amount so that it cannot be expressed in \ (k \) banknotes.

thinking

It can be converted to find the minimum amount that must be expressed in \ (k + 1 \) notes, and define \ (s = k + 1 \). For the \ (I \) note, make \ (s \) subtract \ (10^{a_{i + 1} - a_i} - 1 \). If it cannot be subtracted or has reached the note with the largest face value, directly output the current number and fill it with \ (a_i \) \ (9 \).

code

#include<cstdio>
#include<cstring>
using namespace std;

const int MAXN = 10;
const int base[10] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};

bool vis[MAXN];
int a[MAXN], ans[MAXN];

int main() {
    int T;

    scanf("%d", &T);
    while(T--) {
        int n, k;

        scanf("%d%d", &n, &k);
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            vis[a[i]] = 1;
        }
        int s = k + 1, p = n;
        for(int i = 1; i <= n; i++) {
            if(i == n) {
                ans[i] = s;
                break;
            }
            if(s > base[a[i + 1] - a[i]] - 1) {
                ans[i] = base[a[i + 1] - a[i]] - 1;
                s -= base[a[i + 1] - a[i]] - 1;
            } else {
                ans[i] = s;
                p = i;
                break;
            }
        }
        printf("%d", ans[p]);
        for(int i = 1; i <= a[p]; i++) {
            printf("9");
        }
        printf("\n");
    }

    return 0;
}

E - Arena

meaning of the title

There are \ (n \) heroes in the arena. Each hero's HP is \ (a_i \) (\ (1 \leq a_i \leq x \)). In each battle, each hero will cause \ (1 \) points of damage to all other heroes. When the HP drops to \ (0 \), the hero will exit. If there is only one hero after several battles, the hero is the winner.

Find out how many health schemes make there no winner in the end. The answer is \ (998244353 \). The two schemes are different if and only if at least one hero has different HP.

thinking

There seems to be no idea to think directly about the number of schemes without winners. We might as well consider calculating the number of schemes with winners.

Define \ (f_{i, j} \) as the number of schemes with \ (I \) heroes and maximum health value of \ (j \), and you can get the state transition equation:

\[f_{i, j} = \sum_{k = 0}^{i - 1}f_{i - k, j - i + 1}(i - 1)^k C_i^k \]

Where \ (k \) is the number of heroes exiting this battle.

It should be noted that the time limit of this problem will lead to the general fast power. My method is to preprocess the power. See the code for details.

code

#include<cstdio>
#include<algorithm>
using namespace std;

const int MAXN = 500 + 5;
const int MOD = 998244353;

long long C[MAXN][MAXN], f[MAXN][MAXN], qpow[MAXN][MAXN];
int n, m;

void init() {
	C[0][0] = 1;
	for(int i = 1; i <= n; i++) {
		C[i][0] = 1;
		for(int j = 1; j <= i; j++) {
			C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
		}
	}
	for(int i = 1; i < MAXN; i++) {
		qpow[i][0] = 1;
		for(int j = 1; j < MAXN; j++) {
			qpow[i][j] = qpow[i][j - 1] * i % MOD;
		}
	}
}

int main() {
	scanf("%d%d", &n, &m);
	init();
	for(int j = 1; j <= m; j++) {
		f[1][j] = j;
		f[2][j] = j * (j - 1);
	}
	for(int i = 3; i <= n; i++) {
		for(int j = i; j <= m; j++) {
			for(int k = 0; k < i; k++) {
				f[i][j] = (f[i][j] + (f[i - k][j - i + 1] * qpow[i - 1][k]) % MOD * C[i][k] % MOD) % MOD;
			}
		}
	}
	printf("%lld\n", ((qpow[m][n] - f[n][m]) % MOD + MOD) % MOD);
	
	return 0;
}

(the remaining questions will be filled in later)

(Goo Goo)

Tags: CodeForces

Posted on Sun, 05 Dec 2021 21:10:30 -0500 by thallium6