hdu 5207 Greatest Greatest Common Divisor【筛法】【思维】

来源:互联网 发布:百视通网络电视要密码 编辑:程序博客网 时间:2024/06/05 08:42

Greatest Greatest Common Divisor

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1350    Accepted Submission(s): 562


Problem Description
Pick two numbers ai,aj(ij) from a sequence to maximize the value of their greatest common divisor.
 


Input
Multiple test cases. In the first line there is an integerT, indicating the number of test cases. For each test cases, the first line contains an integern, the size of the sequence. Next line contains n numbers, from a1 to an.1T100,2n105,1ai105. The case for n104 is no more than 10.
 


Output
For each test case, output one line. The output format is Case #x:ans,x is the case number, starting from 1,ans is the maximum value of greatest common divisor.
 


Sample Input
241 2 3 433 6 9
 


Sample Output
Case #1: 2Case #2: 3


这里暴力gcd是一定会TLE的、所以我们这里要应用一点小技巧、我们知道,如果一个数是a的因子数,并且也是b的因子数,那么这个数就叫a,b的公约数,这里我们可以枚举约数,而非每个数都求最大公约数、

首先 ,我们要做的事是要先找到这组数据中最大的那个:

        memset(ha,0,sizeof(ha));        int n;        int maxn=-0x1f1f1f1f;        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            int k;            scanf("%d",&k);            ha[k]++;            maxn=max(maxn,k);        }

这样我们就对所有的数据输入完毕,并且找到了这组数据最大的值maxn,那么我们知道,这组数据最大的因子数就是这个maxn,所以我们枚举因子数的时候,枚举到maxn就可以停了~

 

        int output=0;        for(int i=1;i<=maxn;i++)//枚举因子数        {            int cont=0;            for(int j=i;j<=maxn;j+=i)//找这个因子数的倍数,表明i是j的因子数            {                if(ha[j]==1)                cont++;                if(ha[j]>=2)output=j;             }            if(cont>=2)//如果有i事两个以上数的因子数,那么它就是一个公约数,不一定这次是最大的,但是这样找下去总能找的到、            output=max(output,i);        }

最后上完整的AC代码:

#include<stdio.h>#include<iostream>#include<string.h>using namespace std;int ha[100005];int main(){    int kase=0;    int t;    scanf("%d",&t);    while(t--)    {        memset(ha,0,sizeof(ha));        int n;        int maxn=-0x1f1f1f1f;        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            int k;            scanf("%d",&k);            ha[k]++;            maxn=max(maxn,k);        }        int output=0;        for(int i=1;i<=maxn;i++)        {            int cont=0;            for(int j=i;j<=maxn;j+=i)            {                if(ha[j]==1)                cont++;                if(ha[j]>=2)                output=j;            }            if(cont>=2)            output=max(output,i);        }        printf("Case #%d: %d\n",++kase,output);    }}








0 0
原创粉丝点击