Educational Codeforces Round 13

Educational Codeforces Round 13

A Johny Likes Numbers

做法:假设答案为\(t * k\)考虑$(t - 1) * k $,所以答案显然 为 $ n-n$ \(\%\) $k+k $
代码:

void solve(){
    int n, k;
    cin >> n >> k;
    cout << n - (n % k) + k  << endl;
}

B The Same Calendar

做法:考虑对\(7\)取模,闰年\(+2\),平年\(+1\),在考虑答案年和输入的年份是不是同闰同平即可。
代码:

int pd(int n) {
    if(n % 400 == 0 || (n % 4 == 0 && n % 100 != 0)) return 1;
    return 0;
}
void solve(){
    int n;
    cin >> n;
    int pdq = pd(n);
    int now = 365 + pdq;
    while(1) {
        n++;
        if(pd(n)) {
            now += 366;
        }
        else now += 365;
        if(now % 7 == 2 && pdq == 1 && pd(n) == 1) break;
        if(now % 7 == 1 && pdq == 0 && pd(n) == 0) break;
    }
    cout << n << endl;
}

C Joty and Chocolate

做法:简单容斥一下即可,答案为:

\[\left \lfloor x / a \right \rfloor * p + \left \lfloor x / b \right \rfloor * q - \left \lfloor x / (lcm(a,b)) \right \rfloor * min(a,b) \]

代码:

void solve(){
    int n , a, b , p , q;
    cin >> n >> a >> b >> p >> q;
    cout << n / a * p + n / b * q - n /((a * b) / __gcd(a,b)) * min(p , q) << endl;
}

D Iterated Linear Function

做法:两种显然的做法,一个是矩阵快速幂一下,还有也可以直接手拆这个公式去看,其实就是一个等比加一个\(A^{n} * x\),特判\(A == 1\)
代码:

int qmi(int a, int k) {
    int res = 1;
    while(k) {
        if(k & 1) {
            res = res * a % mod;
        }
        k >>= 1;
        a = a * a % mod;
    }
    return res;
}
void solve(){
    int a, b,n , x;
    cin >> a >> b >> n >> x;
    if(a == 1) {
        cout << (x + n % mod * b % mod) % mod << endl;
    }
    else {
        int ans = 0;
        ans = (qmi(a,n) * x + b * (((qmi(a, n) - 1) % mod + mod) % mod) % mod * qmi(a - 1, mod - 2) % mod) % mod;
        cout << ans << endl;
    }
}

E Another Sith Tournament

做法:看到数据范围想到状态压缩,比较容易想到的做法是直接考虑二进制每一位,\(1\)表示选手还活着,\(0\)表示选手被淘汰。
这样想了之后,我们可以去想如何去转移胜率的关系,如果将有的1去排列一遍对局情况,复杂度显然不能接受,所以我们可以给状态加一维,所以最后的状态定义为:
\(F_{n,i}\)表示在二进制n的状态下,i为擂主,1号的胜率。
转移方程可以考虑,当前二进制串下,如果出现了多个1,我们考虑这两个人互相击败对方,两种情况,概率相加,这样就是

\[F_{n,j} = max(F_{n,j},P_{j,k} * F_{n - 2^{k},j} + P_{k,j} * F_{n - 2^{j},k}) \]

代码:

void solve(){
    int n;
    cin >> n;
    
    for (int i = 0;i < n;i ++) {
        for (int j = 0;j < n;j ++) {
            cin >> p[i][j];
        }
    }
    f[1][0] = 1.0;
    for (int i = 2;i < (1 << n);i ++) {
        for (int j = 0;j < n;j ++) {
            if(i >> j & 1) {
                // cout << i << ' ' << j << endl;
                for (int k = 0;k < n;k ++) {
                    if(i >> k & 1) {
                        f[i][j] = max(f[i][j] , p[j][k] * f[i - (1 << k)][j] + p[k][j] * f[i - (1 << j)][k]);
                    }
                }
            }
        }
    }
    if(n == 1) {
        printf("%.20lf\n",1.0);
        return ;
    }
    double ans = 0;
    // for (int i = 0;i < n;i ++) printf("%.10lf\n", f[(1 << n) - 1][i]);
    for (int i = 0;i < n;i ++) ans = max(ans, f[(1 << n) - 1][i]);
    printf("%.15lf\n",ans);
}
posted @ 2023-01-13 17:31  zwhqwq  阅读(42)  评论(0编辑  收藏  举报