前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CodeForces - 1047CEnlarge GCD(这题很难,快来看题解,超级详细,骗浏览量)

CodeForces - 1047CEnlarge GCD(这题很难,快来看题解,超级详细,骗浏览量)

作者头像
风骨散人Chiam
发布2020-10-28 10:37:06
4590
发布2020-10-28 10:37:06
举报
文章被收录于专栏:CSDN旧文

C. Enlarge GCD time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output Mr. F has n positive integers, a1,a2,…,an.

He thinks the greatest common divisor of these integers is too small. So he wants to enlarge it by removing some of the integers.

But this problem is too simple for him, so he does not want to do it by himself. If you help him, he will give you some scores in reward.

Your task is to calculate the minimum number of integers you need to remove so that the greatest common divisor of the remaining integers is bigger than that of all integers.

Input The first line contains an integer n (2≤n≤3⋅105) — the number of integers Mr. F has.

The second line contains n integers, a1,a2,…,an (1≤ai≤1.5⋅107).

Output Print an integer — the minimum number of integers you need to remove so that the greatest common divisor of the remaining integers is bigger than that of all integers.

You should not remove all of the integers.

If there is no solution, print «-1» (without quotes).

Examples inputCopy 3 1 2 4 outputCopy 1 inputCopy 4 6 9 15 30 outputCopy 2 inputCopy 3 1 1 1 outputCopy -1 Note In the first example, the greatest common divisor is 1 in the beginning. You can remove 1 so that the greatest common divisor is enlarged to 2. The answer is 1.

In the second example, the greatest common divisor is 3 in the beginning. You can remove 6 and 9 so that the greatest common divisor is enlarged to 15. There is no solution which removes only one integer. So the answer is 2.

In the third example, there is no solution to enlarge the greatest common divisor. So the answer is −1.

这道题是说删最少的数字使得,数列的最大公约增大。这道题要明白第一点,输出-1的情况,当输入数字都是一样的时候,其他情况全都有解,至少有一个N-1的解。 先对数列求整体的最小公倍数。假设第一个与第二个的小公倍数a=gcd(x1,x2)则第二个与第三个的是b=gcd(a,x3),即x1,x2,x3的最小公倍数。以此类推即可求出所有数的最大公约数,本以为会超时,没想到922ms过了。 那么要想变大,就要从比最大公约数大一个的开始枚举,好在如果先枚举过2之后4,6,8,就都不用枚举了,实际上是没举素数,但是埃氏筛法也很费时间,加上就超时,这里就用了埃氏筛法的思想。我是用桶的方法存的数据,不然重复元素不好处理,这样根据下标就能判断这个数在哪里,有几个。每次枚举出的都是按最大公约数枚举,这样刚好能处理。 ps: 2 4 8 18 34 44 最大公约数是2 从3开始枚举 cnt+=a[3]=0; cnt+=a[6]=0; … cnt+=a[18]=1; … ans=5; 然后是4; cnt=3; ans=4; 然后是5 cnt=0; ans=6; 布拉布拉,就写就是了。 上界肯定是比第一大数小的数,但是小多少,不清楚,直接枚举到最大数即可。刚刚有优化了一下,发现很多地方都可以减少时间消耗。跑出来了700ms的好成绩,哈哈哈哈。

代码语言:javascript
复制
#include <bits/stdc++.h>
using namespace std;
const int MAX =1.5e7 + 10;
int jishu[MAX], a[MAX];
int flag=0,maxn=0 ,n, d = 0, ob;
int main()
{
	scanf("%d",&n);
	for (int i=0; i<n; ++i)
	{
		scanf("%d", &ob);
		maxn=max(maxn,ob);
		a[ob]++;
		if  (i==0)d = ob;
		d = __gcd(d,ob);//艾玛,省老多事了。
	}
	if(a[ob]==n)
    {
        	printf("-1\n");
        return 0;
    }
	int ans = n;
	for (int i=d + 1;i<=maxn; ++i)
		if (jishu[i]==0)
		{
			int ct = 0;
			for (int j = i; j <= maxn; j += i)
				jishu[j] = 1, ct += a[j];
			ans = min(ans,n-ct);
		}
	printf("%d\n",ans);
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/05/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档