Educational Codeforces Round 79 (Div. 2)

比赛链接:https://codeforces.com/contest/1279

A - New Year Garland

题意

给出三种颜色花环的数量,要求相同颜色不相邻,问能否用完所有花环。

思路

考虑无解的情况,即较少的两种花环个数 + 1 < 较多的花环个数(+ 1 是因为较多的可以放在首尾),除此外的情况都是有解的。

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int a[3]; for (int &i : a) cin >> i;
    sort(a, a + 3);
    if (a[0] + a[1] + 1 >= a[2]) cout << "Yes" << "\n";
    else cout << "No" << "\n";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

B - Verse For Santa

题意

圣诞节快到了,Vasya 想要给圣诞老人背诵圣诞诗,每首诗需要背诵 ai 秒,圣诞老人最多听 s 秒,现在最多可以跳过一首诗,问是否需要以及要跳过哪首诗。

思路

加和到第一次超过 s,这时必须要跳过一个,跳过用时最多的对后面的背诵一定是最优的。

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n, s; cin >> n >> s;
    int a[n]; for (int &i : a) cin >> i;
    for (int i = 0; i < n; i++) {
        s -= a[i];
        if (s < 0) {
            cout << max_element(a, a + i + 1) - a + 1 << "\n";
            return;
        }
    }
    cout << "0" << "\n";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

C - Stack of Presents

题意

圣诞老人有一个礼物栈,现在要按照顺序给小朋友礼物,如果一个礼物在栈顶,用时 1 秒就可以取到,否则因为要把上面的 k 个礼物取出来再放回去,所以要用时 2k + 1 秒,不过放回去的时候可以按照任意顺序,问为所有小朋友取完礼物所需的最少时间。

思路

记录所取礼物的最大深度,如果有礼物大于当前最大深度,用时为 2 x (该礼物深度 - 已取礼物个数) + 1,取完该礼物后可以将之前的礼物按照余下小朋友礼物列表排放,接下来取到时只需 1 秒。

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n, m; cin >> n >> m;
    int a[n]; for (int &i : a) cin >> i;
    int b[m]; for (int &i : b) cin >> i;

    int pos[n + 1]; 
    for (int i = 0; i < n; i++) {
        pos[a[i]] = i;
    }

    long long ans = 0;
    for (int i = 0, dep = 0; i < m; i++) {
        if (pos[b[i]] < dep) {
            ++ans;
        } else {
            ans += 2 * (pos[b[i]] - i) + 1;
            dep = pos[b[i]];
        }
    }
    cout << ans << "\n";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

D - Santa's Bot

题意

圣诞老人有一个礼物分发机器人,每次会随机选取一个小朋友并随机从他的愿望单中选取一个礼物再随机地分发给一个小朋友,问分发正确的概率,对 998244353 取模。

思路

随机地选取某个小朋友—— 1 / n,

随机地从愿望单中选取一个礼物—— 1 / a[i].size(),

随机分发的正确率—— cnt[x] / n,cnt[x] 是该礼物在多少小朋友的愿望单里,

即对于每个礼物 x,分发正确的概率是 1 / n * 1 / a[i].size() * cnt[x] / n,对所有礼物求和即可。

代码

#include <bits/stdc++.h>
using namespace std;

const int mod = 998244353;
const int M = 1e6 + 100;

vector<int> a[M];
int cnt[M];

int fpow(int a, int b) {
    int res = 1;
    while (b) {
        if (b & 1) res = 1LL * res * a % mod;
        a = 1LL * a * a % mod;
        b >>= 1;
    }
    return res;
}

int inv(int n) {
    return fpow(n, mod - 2);
}

int main() {
    int n; cin >> n;
    for (int i = 0; i < n; i++) {
        int k; cin >> k;
        a[i].resize(k);
        for (int &j : a[i]) cin >> j, ++cnt[j];
    }
    int ans = 0;
    for (int i = 0; i < n; i++) {
        for (int x : a[i]) {
            ans = (ans + (1LL * inv(n) * inv(a[i].size()) % mod * (1LL * cnt[x] * inv(n) % mod)) % mod) % mod;
        }
    }
    cout << ans;
}

 

posted @ 2020-04-20 23:11  Kanoon  阅读(137)  评论(0)    收藏  举报