删除一个数字之后数列gcd最大

★实验任务

顾名思义,互质序列是满足序列元素的 gcd 为 1 的序列。比如[1,2,3], [4,7,8],都是互质序列。[3,6,9]不是互质序列。现在并不要求你找出一个互质 序列,那样太简单了!真正的问题描述是:给定一个序列,删除其中一个元素使 得剩下元素的 gcd 最大,输出这个 gcd。

★数据输入

输入第一行为一个正整数 n。第二行为 n 个正整数 ai(1<=ai<=10^9)。 80%的数据 2<=n<=1000. 100%的数据 2<=n<=100000.

★数据输出

输出一个正整数,表示最大的 gcd。

测试样例

输入:
3
1 1 1

输出:
1

解题思路:显然通过暴力是会超时,删除一个数那我们就要将这个数组每个数都遍历一遍,但是在这个过程中肯定会有喝多重复的计算一些书的gcd过程,所以对这些重复计算的过程进行优化才能解出。用两个数组进行从前往后的每个数之前的所有数的gcd和从后往前的每个数之后的所有数的gcd存储,然后整个过程就简单多了。

代码:

 
            #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>

using namespace std;
int a[100005], qian[100005], hou[100005];

int gcd(int a, int b)
{
	if (a < b) { int tmp = a; a = b; b = tmp; }
	int tmp;
	while (b != 0)
	{
		tmp = b; b = a%b; a = tmp;
	}
	return a;
}

int Max(int a, int b)
{
	return a > b ? a : b;
}

int main()
{
	int n, i, j;
	cin >> n;
	for (i = 0; i < n; i++)cin >> a[i];
	qian[0] = a[0]; hou[n-1] = a[n - 1];
	for (i = 1; i < n; i++)qian[i] = gcd(qian[i - 1], a[i]);
	for (i = n - 2; i >= 0; i--)hou[i] = gcd(hou[i + 1], a[i]);
	int max = qian[n - 1];
	for (i = 0; i < n; i++)
	{
		if (i == 0)max = Max(max, hou[1]);
		else if (i == n - 1)max = Max(max, qian[n - 2]);
		else max = Max(max, gcd(qian[i - 1], hou[i + 1]));
	}
	cout << max << endl;
	return 0;
}
        
posted @ 2017-11-10 11:27  heihuifei  阅读(820)  评论(0编辑  收藏  举报