前缀和+后缀和题目2 Coprime Sequence

前缀和+后缀和题目2 Coprime Sequence

在这里插入图片描述

  1. 题目分析:

           输入一个整数n,代表测试集合,而每个测试集合,又需要先输入一个数字m,代表将输入数字的数目,每一个测试案例都构成了一个序列。
           题目所问是在每个序列中,任意删除一个,那么求所得序列的最大约数。问什么时候可以让修改后的序列最大公约数最大。
           我们知道GCD(a,b,c) = GCD(GCD(a,b),c) = GCD(a,GCD(b,c))
           GCD是最大公约数的意思
           我们可以知道这个定理很显然,但是具体证明需要用到数论里的知识,在这里就先不叙述,有兴趣的伙伴可以观看数论方面书籍。

  2. 算法设计:
           我们可以设置一个前缀,即保留前n个数的最大公约数pre[],从n开始后面的最大公约数tail[]。
           我们还需要辗转相除递归求公约数。

  3. 知识点
           1.快速求公约数,辗转相除,或更相减损。
           2.前缀和,后缀和。

  4. 代码

#include <stdio.h>
int temp[100000];
int pre[100000];
int tail[100000];
int getGCD(int a,int b)
{
    if(a>b)
    {
         int temp = a; 
         a = b;
         b = temp;
    }
    if(b%a==0)
    return a;
    else
    return getGCD(a,b%a);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
        {
             int n;
             scanf("%d",&n);
             for(int k =1;k<=n;k++)
             {
                  scanf("%d",&temp[k]);
             }
             pre[1] = temp[1];
             tail[n] = temp[n];
             for(int k = 2;k<=n;k++)
                {
                     pre[k] = getGCD(pre[k-1],temp[k]);
                }
             for(int k=n-1;k>0;k--)
                {
                     tail[k] = getGCD(tail[k+1],temp[k]);
                }
               int max = tail[2];
               if(pre[n-1]>max)
               max = pre[n-1];
            for(int i =2;i<n;i++)
               {
                    if(getGCD(pre[i-1],tail[i+1])>max)
                    max = getGCD(pre[i-1],tail[i+1]);
               }
              printf("%d\n",max);
             
        }return 0;
}

over

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值