Codeforces Round #511 (Div. 2)C+暴力筛

题目链接:http://codeforces.com/contest/1047/problem/C
题目大意:给你长度为n的数组,这个数组的gcd为m,输出能够使m变大的情况下至少要删除多少个数,如果删除数字不能使m变大的话,就为没有答案,输出-1

思路:把这些数除以他们所有数的最大公因数,保存在数组s1中,这s1中具有倍数(至少2倍)关系的数最多的个数即为保留的个数。

思考:为什么这样的复杂度没有被T?????

#include<bits/stdc++.h>
using namespace std;

const int N=1.5e7+5, M=3e5+5;
int a[M], s1[N], s2[N];
int main()
{
    memset(s1, 0, sizeof(s1));
    memset(s2, 0, sizeof(s2));
    
    int n, g;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        if(i==0)
            g=a[0];
        else
            g=__gcd(g, a[i]);//所有数的最大gcd1
    }
    for(int i=0;i<n;i++)
    {
        s1[a[i]/g]++;        //所有的数都除以g,统计个数

    }

    //max_s记录s1中有相同gcd2并且gcd>=2的数的最大个数
    //即保留数字的最大个数,因为这些数的gcd3=gcd1*gcd2(gcd2>=2)
    //所以gcd3>gcd1。保留最多则删除最少
    int max_s=0;             
    for(int i=2;i<N;i++)
    {
        //统计具有相同公因数的数字个数
        if(!s2[i])
        {
            int s=0;
            for(int j=i;j<N;j+=i)
            {
                s+=s1[j];
                s2[j]=1;//防止重复访问
            }
            max_s=max(max_s, s);
        }
    }
    printf("%d\n",max_s?n-max_s:-1);

    return 0;
}

全部评论

相关推荐

工作30年还房贷:比赛加学历就已经够了。你要挑点毛病的话,项目写的不行,没有突出深度,你可能做了很多深度工作,但给别人的感觉都是做的很简单的工作。
点赞 评论 收藏
分享
产品经理傅立叶:1.建议把个人信息码一下 2.简历的排版还得优化一下,看上去有点乱,另外有一个实习经历实习时间好像多写了一个; 3.实习产出要量化
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务