CF1744D题解

题目传送门。

由于题目有了样例解释,所以直接上思路。

可以非常简单地用 get2 函数求出一个数所有因子中 22 的数量:

int get2(int x) {
	int cnt=0;
	while(1) {
		if(x%2==1)break;
		x/=2;
		cnt++;
	}
	return cnt;
}

那么我们可以把 11nn 中所有数的所有因子中 22 的数量存储在一个名字叫 two 的数组中。

同理,可以将每一个 aia_i 的所有因子中 22 的数量存储在一个名字叫 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];
}

接着,如果总和还没有 nn 大,则一定不满足,输出 1-1

如果 two2 的总和已经 n\geq n,则输出 00

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;
}
posted @   Weslie_qwq  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示