Educational Codeforces Round 13

Educational Codeforces Round 13

https://codeforces.com/contest/678
4/6:ABCD (1h)

前4题都很简单,E应该是个撞鸭dp但是我想不出来

A. Johny Likes Numbers

#include <bits/stdc++.h>

using namespace std;

int main () {
    int n, k;
    cin >> n >> k;
    int cnt = (n + k - 1) / k * k;
    if (n % k == 0) cnt += k;
    cout << cnt;
}

B. The Same Calendar

累加天数和,余数与当年相同且同为/同不为闰年即可。

#include <bits/stdc++.h>

using namespace std;
int n, sum;

bool isLeap (int x) {
    if (x % 400 == 0)       return  true;
    if (x % 4 == 0 && x % 100)  return true;
    return false;
}

int main () {
    cin >> n;
    if (isLeap (n)) {
        sum += 366;
        for (int i = n + 1; ; i ++) {
            int dx = isLeap (i);
            sum += 365 + dx;
            //cout << i << ' ' << dx << ' ' << sum << ' ' << sum % 7 << endl;
            if (dx && sum % 7 == 2) {
                cout << i;
                break;
            }
        }
    }
    else {
        sum += 365;
        for (int i = n + 1; ; i++) {
            int dx = isLeap (i);
            sum += 365 + dx;
            //cout << i << ' ' << dx << ' ' << sum << ' ' << sum % 7 << endl;
            if (!dx && sum % 7 == 1) {
                cout << i;
                break;
            }
        }
    }
}

C. Joty and Chocolate

数学+简单容斥

#include <bits/stdc++.h>
#define int long long

using namespace std;
int n, a, b, p, q, cnta, cntb, cntab;

signed main () {
    cin >> n >> a >> b >> p >> q;
    cnta = n / a - (1 + a - 1) / a + 1;
    cntb = n / b - (1 + b - 1) / b + 1;
    int ab = (a * b) / __gcd (a, b);
    cntab = n / ab - (1 + ab - 1) / ab + 1;
    //cout << cnta << ' ' << cntb << ' ' << cntab << endl;
    cout << (cnta - cntab) * p + (cntb - cntab) * q + cntab * max (p, q);
}

//1-n里面有多少个x的倍数

D. Iterated Linear Function

复合函数推是式子:

\[A^nx+\frac{A^n-1}{A-1}B \]

除法那里要用逆元+注意特判 \(A=1\)

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int p = 1e9 + 7;
int a, b, n, x;

int qmi(int a, int k) {
	int ans = 1;
	while (k) {
		if (k & 1)	ans = ans * a % p;
		k >>= 1;
		a = a * a % p;
	}
	return ans;
}

signed main () {
    cin >> a >> b >> n >> x;
    if (a == 1) {
        cout << (x + n % p * a % p * b % p) % p;
        return 0;
    }
    int da = qmi (a, n), inv = qmi (a - 1, p - 2);
    //cout << da;
    cout << (x % p * da + (da - 1) * inv % p * b) % p;
}

//A^n * x + (1-A^n)/(1-A) * B

E. Another Sith Tournament

状压dp。
看了题解的状态表示之后我直呼妙妙!
\(f_{i,j}\) 表示状态 \(i\) 中,\(j\) 是擂主。
转移:逆推。枚举上一个状态下的擂主,然后依次转移,式子为:
\(f_{i,j}=max(f_{i-(1<<j),k}\cdot a_{k,j}, f_{i-(1<<k),j}\cdot a_{j,k})\)
含义为:上一轮的擂主可能是 \(j,k\),二者 \(pk\) 之后的胜者转移到目前状态。
要注意转移的过程中要确保当前状态下 \(1\) 还活着
注意==的优先级比位运算高

#include <bits/stdc++.h>

using namespace std;
const int N = 20;
int n;
double a[N][N], f[1<<N][N], ans;

int main () {
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> a[i][j];
        }
    }
    f[1][0] = 1;
    for (int i = 2; i < (1 << n); i++) {
        for (int j = 0; j < n; j++) {
            if ((i >> j & 1) == 0)    continue; //1已经死了
            for (int k = 0; k < n; k++) {
                if (k == j || (i >> k & 1) == 0)  continue;
                f[i][j] = max (f[i][j], f[i - (1 << j)][k] * a[k][j] + f[i - (1 << k)][j] * a[j][k]); //k赢+j赢
            }
        }
    }
    for (int i = 0; i < n; i++)  ans = max (ans, f[(1 << n)-1][i]);
    cout << fixed << setprecision (9) << ans;
}

//==优先级比位运算高

F. Lena and Queries

线段树分治。
板子题这里
待补

posted @ 2023-01-07 11:45  Sakana~  阅读(46)  评论(0编辑  收藏  举报