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 a
i
,a
j
(i≠j)
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 a
1![]()
to a
n![]()
.1≤T≤100,2≤n≤10
5
,1≤a
i
≤10
5![]()
.
The case for n≥10
4![]()
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
2 4 1 2 3 4 3 3 6 9
Sample Output
Case #1: 2 Case #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);
}
}