Codeforces Round 963 (Div. 2)

A. Question Marks

思路:把 A B C D A B C D ABCD的个数和 n n n m i n min min

int n; cin >> n;
    map<char, int> mp;
    string s; cin >> s;
    for (auto i : s) mp[i] ++;
    int ans = 0;
    if (mp['A']) ans += min(n, mp['A']);
    if (mp['B']) ans += min(n, mp['B']);
    if (mp['C']) ans += min(n, mp['C']);
    if (mp['D']) ans += min(n, mp['D']);
    cout << ans << '\n';

B. Parity and Sum

思路:全奇和全偶操作次数为 0 0 0,剩下的情况一定最后全是奇数,又分两种情况,从最小的偶数依次递增开始操作,从最大的偶数依次递减开始操作,最后两者取 m i n min min即可

void solve() {
    int n; cin >> n;
    vector<int> a(n + 1), ji, ou;
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        if (a[i] & 1) ji.push_back(a[i]);
        else ou.push_back(a[i]);
    }
    if (!ji.size() || !ou.size()) {
        cout << 0 << '\n';
        return ;
    }
    priority_queue<int> pq;
    for (auto i : ji) pq.push(i);
    int ans = 0;
    sort(ou.begin(), ou.end());
    for (auto i : ou) {
        while (true) {
            auto t = pq.top();
            pq.push(t + i);
            ans ++;
            if (t >= i) break;
        }
    }
    sort(ji.rbegin(), ji.rend());
    sort(ou.rbegin(), ou.rend());
    int res = 0;
    if (ou[0] > ji[0]) res += 2;
    else res ++;
    res += (int)ou.size() - 1;
    cout << min(ans, res) << '\n';
}

C. Light Switches

思路:感觉这题一眼思路,因为有周期性,所以在前面的周期不能同时亮,后面的周期也一定不行,要让灯同时亮,一定要让所有灯在一个区间里面,所以我们让所有的灯尽量靠近最晚开始亮的灯,把区间处理出来最后取交集,如果最后的 l l l大于 r r r肯定不行,否则答案是 l l l

void solve() {
    int n, k; cin >> n >> k;
    vector<int> a(n + 1);
    map<int, int> mp;
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        mp[a[i]] ++;
    }
    if (k == 1 && mp.size() != 1) {
        cout << -1 << '\n';
        return ;
    }
    sort(a.begin() + 1, a.end());
    int l = a[n], r = a[n] + k - 1;
    vector<array<int, 2>> seg;
    for (int i = 1; i < n; i ++) {
        int lt1 = a[i] + (l - a[i] + 2 * k - 1) / (2 * k) * (2 * k);
        int rt1 = lt1 + k - 1;
        int lt2 = a[i] + (l - a[i]) / (2 * k) * (2 * k);
        int rt2 = lt2 + k - 1;
        int r1 = min(rt1, r) - max(lt1, l);
        int r2 = min(rt2, r) - max(lt2, l);
        if (r1 >= r2) seg.push_back({lt1, rt1});
        else seg.push_back({lt2, rt2});
    }
    for (int i = 0; i < seg.size(); i ++) {
        auto [lt, rt] = seg[i];
        l = max(l, lt);
        r = min(r, rt);
    }
    if (l > r) cout << -1 << '\n';
    else cout << l << '\n';
}

D. Med-imize

看看能不能补吧

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值