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;
    }
  • 相关阅读:
    zend framework多模块配置
    java解析xml的几种方式
    jdbc操作步骤和preparedStatment相比Statment的好处
    Android UI 之实现多级列表TreeView
    python小游戏实现代码
    【iOS知识学习】_UITableView简介
    根据指定电话号码得到通讯录上的姓名
    HDU 4705 Y
    C#实现的内存分页机制的一个实例
    【编程程序猿艺术】学习记录1:指针向左翻转法的旋转串
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007245.html
Copyright © 2011-2022 走看看