数据结构_coprime_sequence(互质序列)

coprime_sequence(互质序列)

 

问题描述

  顾名思义,互质序列是满足序列元素的 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


输入示例 输出示例
5
2 2 2 3 2
2


输入示例 输出示例
4
1 2 4 8
2


Hint
  最大公因数缩写是 gcdgcd(a,b,c)=gcd(a,gcd(b,c)).

 

 

解题思路

  暴力算法小规模可以,但是复杂度达到O(n^2),大规模数据超时。因此必须采用更好的算法。

  期初,我的想法是将从左到右算过的数据存下来,即开一个数组,将第1个数的gcd(本身)存在第1个位置,将第1~2个数的gcd存在第2个位置,1~3个数的gcd存在第3个位置,以此类推。

  而其中第1~n个数的gcd可由gcd(    1~(n-1)的gcd  ,  第n个数 )求得    是递推的过程,复杂度O(n)

  但仅仅这样只比暴力节省一半时间。因此,仿照前面的过程,引入从右到左的gcd计算

  开等长数组left[] right[] ,将 从左到右 和 从右到左 的gcd递推计算结果分别存入left[] 与right[]

  那么除掉下标为 i 的数,其他数的为gcd( left[i-1] , right[i+1])    首尾做特殊判断

  这样遍历一遍,就能找到gcd_max

 

code

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int p[100002] = {0};
 5 int left[100002] = {0};
 6 int right[100002] = {0};
 7 
 8 void swap(int &a, int &b)
 9 {
10     a ^= b;
11     b ^= a;
12     a ^= b;
13 }
14 
15 int Getgcd(int n, int m)
16 {
17     if (n < m) swap(n, m);
18     return n%m == 0 ? m : Getgcd(m, n%m);
19 }
20 
21 int main()
22 {
23 //    freopen("test.txt","r",stdin);
24     int n, i, j;
25     scanf("%d", &n);
26 //    int *p = (int *)malloc(sizeof(int)*n);
27     for (i = 0; i < n; i++)
28         scanf("%d", p + i);
29 
30     int gcd = -1;
31     for(i=0; i<n; i++) //for(i=0;i<n-1;i++)
32     {
33         if(i==0)
34             gcd = p[0];
35         else
36             gcd = Getgcd(p[i],left[i-1]);
37         left[i] = gcd;
38     }
39     for(i=n-1; i>=0; i--) //for(i=n-1;i>0;i--)
40     {
41         if(i==n-1)
42             gcd = p[n-1];
43         else
44             gcd = Getgcd(p[i],right[i+1]);
45         right[i] = gcd;
46     }
47 
48     int maxgcd = -1;
49     for(i=0; i<n; i++) // except p[i]
50     {
51         if(i==0)
52             gcd = right[1];
53         else if(i==n-1)
54             gcd = left[n-2];
55         else
56             gcd = Getgcd(left[i-1],right[i+1]);
57         if(gcd>maxgcd) maxgcd = gcd;
58     }
59     printf("%d\n",maxgcd);
60 
61 //    free(p);
62     return 0;
63 }

 

posted @ 2017-09-22 21:57  cbattle  阅读(1302)  评论(0编辑  收藏  举报