zoukankan      html  css  js  c++  java
  • 数据结构_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
    ",maxgcd);
    60 
    61 //    free(p);
    62     return 0;
    63 }
  • 相关阅读:
    C#2.0 对AD的简单操作
    启用sqlclr
    项目管理杂谈
    使用目录服务和 Visual C# .NET 向本地系统添加用户
    CSS HACK
    Web2.0设计师工具箱资源网站集锦
    Cookie 的基本知识
    精妙sql语句二
    分页存储过程
    js常用函数
  • 原文地址:https://www.cnblogs.com/cbattle/p/7577344.html
Copyright © 2011-2022 走看看