CF1744D题解
题目传送门。
由于题目有了样例解释,所以直接上思路。
可以非常简单地用 get2 函数求出一个数所有因子中 的数量:
int get2(int x) {
int cnt=0;
while(1) {
if(x%2==1)break;
x/=2;
cnt++;
}
return cnt;
}
那么我们可以把 到 中所有数的所有因子中 的数量存储在一个名字叫 two 的数组中。
同理,可以将每一个 的所有因子中 的数量存储在一个名字叫 two2 的数组中。
那么输入及存储 two,two2 的代码就是这样:
for(int i=1; i<=n; i++) {
two[i]=get2(i);
sum1+=two[i];
cin>>a[i];
two2[i]=get2(a[i]);
sum2+=two2[i];
}
接着,如果总和还没有 大,则一定不满足,输出 ;
如果 two2 的总和已经 ,则输出 ;
if(sum1+sum2<n) {
cout<<-1<<endl;
} else if(sum2>=n) {
cout<<0<<endl;
}
接着,对 two 数组排序;
然后遍历 two 数组,利用贪心找出最小次数,此题终。
sort(two+1,two+n+1,cmp);
sum3=n-sum2;
for(int i=1; i<=n; i++) {
sum3-=two[i];
if(sum3<=0) {
cout<<i<<endl;
break;
}
}
全代码:
#include<iostream>
#include<algorithm>
using namespace std;
int n,a[200001],two[200001],two2[200001],sum1,sum2,sum3,t;
int get2(int x) {
int cnt=0;
while(1) {
if(x%2==1)break;
x/=2;
cnt++;
}
return cnt;
}
int cmp(int a,int b) {
return a>b;
}
int main() {
cin>>t;
while(t--) {
cin>>n;
sum1=0;
sum2=0;
for(int i=1; i<=n; i++) {
two[i]=get2(i);
sum1+=two[i];
cin>>a[i];
two2[i]=get2(a[i]);
sum2+=two2[i];
}
if(sum1+sum2<n) {
cout<<-1<<endl;
} else if(sum2>=n) {
cout<<0<<endl;
} else {
sort(two+1,two+n+1,cmp);
sum3=n-sum2;
for(int i=1; i<=n; i++) {
sum3-=two[i];
if(sum3<=0) {
cout<<i<<endl;
break;
}
}
}
}
return 0;
}

浙公网安备 33010602011771号