Coprime Sequence HDU

来源:互联网 发布:13458淘宝信用查询 编辑:程序博客网 时间:2024/06/05 02:09

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.
Input
The 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.
Output
For each test case, print a single line containing a single integer, denoting the maximum GCD.
Sample Input
331 1 152 2 2 3 241 2 4 8
Sample Output
122

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

思路:首先要清楚一个数列的最大公约数是怎么求的:两个数求出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<cstdio>#include<cstring>#include<iostream>#include<algorithm>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;}

水波.