Problem Description
Do you know what is called ``Coprime Sequence''? That is a sequence consists of
n
positive integers, and the GCD (Greatest Common Divisor) of them is equal to 1.
``Coprime Sequence'' is easy to find because of its restriction. But we can try to maximize the GCD of these integers by removing exactly one integer. Now given a sequence, please maximize the GCD of its elements.
``Coprime Sequence'' is easy to find because of its restriction. But we can try to maximize the GCD of these integers by removing exactly one integer. Now given a sequence, please maximize the GCD of its elements.
Input
The first line of the input contains an integer
T(1≤T≤10)
, denoting the number of test cases.
In each test case, there is an integer n(3≤n≤100000) in the first line, denoting the number of integers in the sequence.
Then the following line consists of n integers a1,a2,...,an(1≤ai≤109) , denoting the elements in the sequence.
In each test case, there is an integer n(3≤n≤100000) in the first line, denoting the number of integers in the sequence.
Then the following line consists of n integers a1,a2,...,an(1≤ai≤109) , denoting the elements in the sequence.
Output
For each test case, print a single line containing a single integer, denoting the maximum GCD.
Sample Input
3 3 1 1 1 5 2 2 2 3 2 4 1 2 4 8
Sample Output
1 2 2
Source
题意:给你n个数字,你可以任意删除一个数字使得剩下的数字的gcd最大,输出最后最大的gcd;
思路:我的思路太暴力,就是正反各一遍特判;gcd后的值会更小或者相等、1和任意数的gcd的值都是1;
另外一种思路就是:正反各存一下起始位置到这个位置的gcd值,然后枚举删点,O(n)的复杂度;
第一种思路对应的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100005;
int a[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
int flag=0;
int v1=a[0],v=0;
for(int i=1; i<n; i++)
{
if(v1==1&&flag==0&&i==1) //特判第一位为1否;
{
flag=1;
v1=a[i];
continue;
}
v=__gcd(a[i],v1);
if(i==n-1&&flag==0) //特判最后一位;
{
if(v<v1) v=v1;
flag=1;
break;
}
if((v==1)&&flag==0) //特判结果为1
{
flag=1;
continue;
}
else if(__gcd(v1,a[i])<__gcd(v1,a[i+1])&&i+1<n&&flag==0)
{
flag=1;
continue;
}
}
v1=v;
int ans=v;
// printf("------------%d\n",ans);
v1=a[n-1],v=0;
flag=0;
for(int i=n-2; i>=0; i--)
{
if(v1==1&&flag==0&&i==n-2)//
{
flag=1,v1=a[i];
continue;
}
v=__gcd(a[i],v1);
if(i==0&&flag==0) //
{
if(v<v1) v=v1;
flag=1;
break;
}
if(v==1&&flag==0) //
{
flag=1;
continue;
}
else if(__gcd(a[i],v1)<__gcd(a[i-1],v1)&&i-1>=0&&flag==0)
{
flag=1;
continue;
}
v1=v;
}
// printf("---------------%d\n",v);
ans=max(ans,v);
printf("%d\n",ans);
}
return 0;
}
第二种思路的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100005;
typedef long long ll;
const ll tomod=1e9+7;
int a[maxn];
int gcd1[maxn],gcd2[maxn];//正着来一遍,反着来一遍;
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
gcd1[0]=gcd2[n+1]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(i==1) gcd1[i]=a[i];
else gcd1[i]=__gcd(gcd1[i-1],a[i]);
}
for(int i=n;i>=1;i--)
{
if(i==n) gcd2[i]=a[i];
else gcd2[i]=__gcd(gcd2[i+1],a[i]);
}
int ans=max(gcd1[n],gcd2[1]);
for(int i=1;i<=n;i++)
{
ans=max(ans,__gcd(gcd1[i-1],gcd2[i+1]));
}
printf("%d\n",ans);
}
return 0;
}