zoukankan      html  css  js  c++  java
  • 随机算法 && CodeForces

    传送门


    解题思路

    先读懂题目:

    有一个等差数列(未排序),共有n个数字,需要你猜出公差和最小的数字。

    你共有60次询问机会,每一次有两种选择:

    • ?i,返回ai的值
    • > i,返回是否存在一个数严格大于i

    最后给出答案。

    思路?

    首先用二分查找得到最大值,使用最多三十次左右询问次数(a<=10^9)。

    然后在用随机数求得公差,即可得到首项。

    那么随机数如何求得公差呢?

    把剩下的次数全部耗尽,寻味数字,排序,求查分数组,把查分数组中的所有差取gcd,则极大概率为正确答案。

    证明?略。

    所以随机算法就是用随机数多次询问某一值,然后高概率求出正确答案。

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<queue>
     8 #include<set>
     9 #include<map>
    10 #include<vector>
    11 #include<iomanip>
    12 #include<ctime>
    13 #include<stack>
    14 using namespace std;
    15 const int maxn=1000000000;
    16 int n,maxa,l,r=maxn,cnt,num,ans,a[1000005];
    17 bool check(int a){
    18     cnt++;
    19     int x;
    20     printf("> %d
    ",a);
    21     fflush(stdout);
    22     scanf("%d",&x);
    23     return x;
    24 }
    25 int gcd(int a,int b){
    26     if(b==0) return a;
    27     return gcd(b,a%b);
    28 }
    29 int main()
    30 {
    31     srand(time(NULL)+20200131);
    32     cin>>n;
    33     while(l<r){
    34         maxa=(l+r)/2;
    35         if(check(maxa)) l=maxa+1;
    36         else r=maxa;
    37     }
    38     maxa=l;
    39     for(int i=cnt+1;i<=60;i++){
    40         printf("? %d
    ",rand()*rand()%n+1);
    41         fflush(stdout);
    42         scanf("%d",&a[++num]);
    43     }
    44     sort(a+1,a+num+1);
    45     ans=a[2]-a[1];
    46     for(int i=3;i<=num;i++){
    47         ans=gcd(ans,a[i]-a[i-1]);
    48     }
    49     cout<<"! "<<maxa-(n-1)*ans<<" "<<ans;
    50     return 0;
    51 }
  • 相关阅读:
    centos7系统初始化脚本
    git上传项目到github
    requests的使用
    zip函数
    mongodb基本操作
    mongodb的安装与配置启动(转)
    jupyter插件与主题
    map函数
    centos7 安装 ffmpeg
    centos7 下 yum 安装Nginx
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14405945.html
Copyright © 2011-2022 走看看