CF1744D 题解
思路
首先,我们可以看每个 中有多少个 (最多能被几个 整除),并添加到 里。如果 ,那就不需要操作,直接输出 。否则,我们就要对每个 也进行拆分,我们设 中有 个 ,那我们就可以对 ( 表示有 个 的数的个数)。记录下来以后,我们肯定是 多的先操作,直到满足要求为止。时间复杂度为 ,足以通过。
代码
# include <bits/stdc++.h>
using namespace std;
int t, n, x, sum, a[20], tot;
int f () {
cin >> n;
memset (a, 0, sizeof a); //多组数据要清空
tot = sum = 0; //多组数据要清零
for (int i = 1; i <= n; ++ i) {
cin >> x;
while (! (x & 1)) //拆 a[i]
x >>= 1, ++ sum;
x = i;
while (! (x & 1)) 拆 i
x >>= 1, ++ tot;
++ a[tot];
tot = 0;
}
if (sum >= n)
return 0;
for (int i = 19; i; -- i) { // 倒着枚举,2 多的先操作
x = sum + a[i] * i;
if (x >= n) //满足要求
return tot + (n - sum + i - 1) / i;
tot += a[i], sum = x;
}
return -1;
}
int main () {
cin >> t;
while (t --)
cout << f () << '\n';
return 0;
}

浙公网安备 33010602011771号