hpuoj 244 MAX GCD

244. Max Gcd

题面 统计数据 讨论 管理

单点时限: 2.0 sec

内存限制: 512 MB

一个数组a ,现在你需要删除某一项使得它们的gcd 最大,求出这个最大值。

输入格式

第一行输入一个正整数n ,表示数组的大小,接下来一行n 个数,第i 个数为ai 。(2≤n≤105,1≤ai≤109)

输出格式

输出删除掉某个数以后的gcd 的最大值。

样例

Input

4
2 4 8 1

Output

2

Input

4
1 2 3 4

Output

1

提示

样例一:删除第四个元素后,2,4,8的最大公因子为2。
样例二:无论删除哪一个,最大公因子都为1。

思路:

这道题我们有两种解法,前缀和后缀维护,枚举删除每个数的最大gcd,对于删除ai后的gcd = gcd(pre[ i - 1] , sa[ i + 1]),其中,pre代表前缀数组的gcd,sa代表后缀输出的gcd

还有就是贪心解法,我个人认为贪心解法挺巧妙的,

首先我们sort降序排一下所有数,令ans = a[ 0 ] , now = a[0],然后我们for遍历我们刚才排序后的数组,假设我们已经遍历到第 i 个数,其中ans代表之前遍历过的所有数删除其中一个数的最大gcd,now表示之前遍历过的所有数的gcd,而后我们更新ans = max(gcd( ans , a[ i ]) , now) ,这里gcd(ans , a[ i ])代表遍历过的序列删除一个数的最大gcd和当前我们正在便利的这个数的gcd,而now则是相当于删除当前a[ i ]的gcd,我们取其中大的,就能够代表扫过a[ i ]后的删除其中一个数的最大gcd了,于是我们此时再更新一下now = gcd(now , a[ i ]) 就行了,这样一直遍历到最后就能够得到答案了

代码:

#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b)
{
    return b ? gcd(b,a % b) : a;
}
const int maxn = 1e5 + 10;
int a[maxn];
bool cmp(int x,int y)
{
    return x > y;
}
int main()
{
    int n;
    while (~scanf("%d",&n))
    {
        for (int i = 0;i < n;i ++)
        scanf("%d",&a[i]);
        sort(a,a + n,cmp);
        int now = a[0],ans = a[0];
        for (int i = 1;i < n;i ++)
        {
            ans = max(gcd(ans,a[i]),now);
            //gcd(ans,a[i])表示不删除a[i]与之前删除一个数的gcd
            //now之前所有数的gcd,相当于删除a[i]后的与之前数的gcd
            //两者取其max就可以表示a[i](包括a[i])之前的删除一个数的最大gcd了
            now = gcd(now,a[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}turn 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值