当前位置:首页 » 《资源分享》 » 正文

51nod3152 取数游戏_ZCH1901的博客

4 人参与  2021年11月02日 14:03  分类 : 《资源分享》  评论

点击全文阅读


3152 取数游戏

有这样一个取数游戏,给出n个正整数(2 <= n <= 100000),在其中选出\left \lceil \frac{n}{2} \right \rceil个数,使得他们的gcd(最大公约数)最大,求这个最大的gcd。

输入

第一行一个整数n
第二行n个正整数

输出

一个一个数表示答案

数据范围

10% 2 <= n <= 10
30% 2 <= n <= 300
60% 2 <= n <= 5000
100% 2 <= n <= 100000

输入样例

输入样例1:
6
6 2 3 4 5 6
输入样例2:
5
5 5 6 10 15

输出样例

输出样例1:
3
输出样例2:
5

这里不给解析,直接放代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime> 
#define maxn 1000000
#define maxt 10
using namespace std;
typedef long long ll; 
int n;
ll  a[maxn+5];
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
int random(int l,int r){
    return (long long )rand()*rand()%(r-l+1)+l;
} 
int sz=0;
ll d[maxn+5];
int cnt[maxn+5];
void divide(ll x){
    sz=0;
    for(ll i=1;i*i<=x;i++){
        if(x%i==0){
            d[++sz]=i;
            if(x/i!=i) d[++sz]=x/i; 
        }
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%I64d",&a[i]); 
    ll ans=0;
    for(int cas=1;cas<=maxt;cas++){
        ll x=a[random(1,n)];
        divide(x);
        sort(d+1,d+sz+1);
        for(int i=1;i<=sz;i++) cnt[i]=0;
        for(int i=1;i<=n;i++){
            int pos=lower_bound(d+1,d+1+sz,gcd(a[i],x))-d;
            cnt[pos]++;
        }
        for(int i=1;i<=sz;i++){
            for(int j=i+1;j<=sz;j++){
                if(d[j]%d[i]==0) cnt[i]+=cnt[j];
            }
        }
        for(int i=sz;i>=1;i--){
            if(cnt[i]*2>=n){
                ans=max(ans,d[i]);
                break;
            }
        }
    }
    printf("%I64d\n",ans);
    return 0;
}


点击全文阅读


本文链接:http://zhangshiyu.com/post/30409.html

样例  输出  输入  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1