Codeforces Round #653 (Div. 3)

B

只有两种操作 \(*2\)\(/6\)

满足这种情况的 \(n=2^a\times3^b\) 才能变成 \(1\)

第一步 把多余的 \(3\) 全部 \(\times2\) 变成 \(6\) 操作次数 \(b-a\)

这之后,\(2\)\(3\) 的因子数量相等即 \(a+(b-a) == b\)

\(n = 2^{a+(b-a)}\times3^{b} \mod 6 == 0\)

第二步 用 \(/6\) 的方式把整个式子变成 \(1\) 操作次数 \(b\)

总共的操作次数即 \(b-a+b\)

代码中 \(cnt2==a,cnt3==b\)

#include <bits/stdc++.h>
using namespace std;
int main() {
    int t,n;
    cin >> t;
    while(t --) {
        cin >> n;
        int cnt2 = 0,cnt3 = 0;
        while(n % 2 == 0) {
            n /= 2;
            cnt2 ++;
        }
        while(n % 3 == 0) {
            n /= 3;
            cnt3 ++;
        }
        if(n == 1 && cnt2 <= cnt3) cout << cnt3 - cnt2 + cnt3 ;
        else cout << -1;
        cout << endl;
    }
    return 0;
}

D

对于这种取余的问题,首先把每个数字都 \(mod\) 一遍然后在余数上做分析

题目要求每个数字只能操作一遍,而且每次 \(x\) 的值都在自增,我们把这种自增看成 \(\mod k\) 下的循环

每个数字需要的操作次数是 \(k-x\mod k\) , 只要找到 \(\max \lbrace k-x\mod k \rbrace\) 即可把所有数字都操作完

但是对于相同的余数来说,第一次把其中一个余数变成 \(k\) 的倍数之后,其他余数还要变,就只能等下一次循环了

所以还要加上 \(k\times m[k-k\mod x]\) ,其中 \(m[]\) 是记录每个余数出现了多少次

综合来看,一起取最大值即可

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main() {
    int t,n,k,x;
    cin >> t;
    while(t --) {
        cin >> n >> k;
        map<LL,LL> m;
        LL ans = -1;
        for(int i = 0;i < n; ++i) {
            cin >> x;
            int re = x % k;
            if(re) ans = max(ans,k - re + k * m[k - re] ++);
        }
        cout << ans + 1 << endl;
    }
    return 0;
}

参考

旺仔

Accelerator

E1

把所有书本分成四种

\(00,01,10,11\) 显然 \(00\) 不可能满足题目条件,我们不考虑

对于\(01,10\) 从小大到排序,然后两个加一起放进 \(11\) (转化)

最后对 \(11\) 排序,取前 \(k\) 个即可

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int main() {
    int n,k;
    cin >> n >> k;
    vector<int> s,a,b;
    int t,x,y;
    for(int i = 0;i < n; ++i) {
        cin >> t >> x >> y;
        if(x && y) s.push_back(t);
        else if(x) a.push_back(t);
        else if(y) b.push_back(t);
    }
    sort(a.begin(),a.end());
    sort(b.begin(),b.end());
    for(int i = 0;i < min(a.size(),b.size()); ++i) {
        s.push_back(a[i] + b[i]);
    }
    sort(s.begin(),s.end());
    if(s.size() < k) cout << -1 << endl;
    else {
        LL ans = 0;
        for(int i = 0;i < k; ++i) {
            ans += s[i];
        }
        cout << ans << endl;
    }
    return 0;
}

参考

issue敲腻害

Harris-H

posted @ 2020-07-17 00:56  南风--  阅读(76)  评论(0编辑  收藏  举报