B
只有两种操作 (*2) 和 (/6)
满足这种情况的 (n=2^a imes3^b) 才能变成 (1)
第一步 把多余的 (3) 全部 ( imes2) 变成 (6) 操作次数 (b-a)
这之后,(2) 和 (3) 的因子数量相等即 (a+(b-a) == b)
(n = 2^{a+(b-a)} imes3^{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-xmod k) , 只要找到 (max lbrace k-xmod k brace) 即可把所有数字都操作完
但是对于相同的余数来说,第一次把其中一个余数变成 (k) 的倍数之后,其他余数还要变,就只能等下一次循环了
所以还要加上 (k imes m[k-kmod 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;
}
参考
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;
}
参考