zoukankan      html  css  js  c++  java
  • 2018牛客网暑期ACM多校训练营(第六场)J(脑洞)

    题目描述:

        给你一个大小为n的数组,数组中的每一个数由A,B,C,D四个参数根据某个奇怪的代码生成,问你在这n个数中选取2两个数,使得lcm(ai,aj)最大。

    题目分析:

        要做出这个题需要一定的脑洞。我们打表可以发现,每次答案可能是最大的数和第二大的数的lcm,或者是最大的数和第三个数的lcm,或者是第二大的数和第三大的数的lcm........我们可以发现,最终的结果必定是在比较大的数集中选出来了。

        因此我们可以大胆猜想,每次我们取前100大,我们每次用O(100*100)的时间暴力求解,最终的答案就是正解。(结果恰好就是如此)。

        可以证明(不会证明)随机两个正整数互质的概率为6/pi^2,因此我们取前100大的数算结果可以满足题目要求。

        (总之这就是一个玄学的题目,需要一定的脑洞)

    代码:

        

    #include <bits/stdc++.h>
    #define maxn 10000005
    using namespace std;
    typedef unsigned long long ll;
    unsigned int n,a,b,c;
    ll num[maxn];
    unsigned x,y,z;
    ll gcd(ll a,ll b){
        return b==0?a:gcd(b,a%b);
    }
    unsigned int tang(){
        unsigned int t;
        x^=x<<16;
        x^=x>>5;
        x^=x<<1;
        t=x;
        x=y;
        y=z;
        z=t^x^y;
        return z;
    }
    bool cmp(ll x,ll y) {return x>y;}
    int main()
    {
        int t,cnt=0;
        scanf("%d",&t);
        while(t--){
            scanf("%u%u%u%u",&n,&a,&b,&c);
            x=a,y=b,z=c;
            for(int i=0;i<n;i++){
                num[i]=tang();
            }
            unsigned int k=min(100u,n);
            nth_element(num,num+k,num+n,cmp);//取前k大
            ll ans=0,ans1=0;
            for (int i=0;i<k;i++)
                for (int j=i+1;j<k;j++){
                    ans=max(ans,num[i]*num[j]/gcd(num[i],num[j]));
                }
            printf("Case #%d: %llu
    ",++cnt,ans);
        }
        return 0;
    }
  • 相关阅读:
    函数式宏定义与普通函数
    linux之sort用法
    HDU 4390 Number Sequence 容斥原理
    HDU 4407 Sum 容斥原理
    HDU 4059 The Boss on Mars 容斥原理
    UVA12653 Buses
    UVA 12651 Triangles
    UVA 10892
    HDU 4292 Food
    HDU 4288 Coder
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007245.html
Copyright © 2011-2022 走看看