Coprime Sequence HDU - 6025

Do you know what is called ``Coprime Sequence''? That is a sequence consists of  nnpositive 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.
InputThe first line of the input contains an integer  T(1T10)T(1≤T≤10), denoting the number of test cases. 
In each test case, there is an integer  n(3n100000)n(3≤n≤100000) in the first line, denoting the number of integers in the sequence. 
Then the following line consists of  nn integers  a1,a2,...,an(1ai109)a1,a2,...,an(1≤ai≤109), denoting the elements in the sequence. OutputFor 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

题意:删除数列中的一个数,使得其他的数的最大公约数最大.

思路:首先要清楚一个数列的最大公约数是怎么求的:两个数求出gcd之后,在用这个gcd与另一个数求新的gcd,在用新的gcd与其他的数求一个新新的gcd........如此反复,知道弄完整个数列,最后得到的就是整个数列的gcd.

所以你可以知道求一个数列的gcd没有顺序之说,随便选那个数开始都可以。

这样我们就很好处理了:

设所求数列为a;

qian[i] 是a[i] 前面所有数字的gcd;

hou[i] 是a[i]  后面所有数字的gcd.

删除a[i]之后,新的数列的gcd就是gcd(qian[i-1], hou[i+1]);所以我们只需要遍历一下就可以求出最大的了.

上代码:

#include
#include
#include
#include
using namespace std;
int gcd(int x,int y)
{
	return y==0 ? x : gcd(y,x%y);
}
int qian[100001];
int hou[100001];
int a[100001];
int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		int n;
		scanf("%d", &n);
		qian[0] = 0;
		hou[0]  = 0;
		for(int i=1; i<=n; i++)
		{
		 	scanf("%d", &a[i]);
		}
		qian[1] = a[1];
		qian[2] = gcd(a[1],a[2]);
		for(int i=3; i<=n; i++)
		{
			qian[i] = gcd(qian[i-1],a[i]);
		}
		hou[n] = a[n];
	    hou[n-1] = gcd(a[n-1],a[n]);
		for(int i=n-2; i>=1; i--)
		{
		    hou[i] = gcd(a[i],hou[i+1]);	
		}	
	    int maxn = max(hou[2],qian[n-1]);
	    for(int i=2; i<=n-1; i++)
	    {
		  maxn = max(maxn, gcd(qian[i-1], hou[i+1]));	
		}
	    printf("%d\n",maxn);
	}
	return 0;
}

水波.

你可能感兴趣的:(ACM大一)