zoukankan      html  css  js  c++  java
  • Codeforces 1114E

    题目链接:http://codeforces.com/problemset/problem/1114/E

    题意:

    交互题,有一个 $n$ 个整数的打乱顺序后的等差数列 $a[1 sim n]$,保证公差为正整数,你可以询问不超过 $60$ 次来找到该等差数列的首项和公差。

    你可以做的询问有两种:

      1、询问是否存在某个数字大于 $x$。

      2、询问序列中第 $i$ 个数是多少。

    题解:

    首先可以用二分的方式找到这个等差数列的最大值,由于 $a[i] in [0,1e9]$,所以最多 $30$ 次询问就可以找到这个最大值。

    然后我们可以用剩下的 $30$ 次询问随机查询一些位置,将这些数作差,求出所有差值的最大公因数,就是公差。

    另外一个需要注意的点是https://codeforces.com/blog/entry/61587这篇博客中提到的,普通的rand()给出的随机数在 $[0,RAND\_MAX]$ 之间,但是只能保证 $RAND\_MAX$ 不小于 $32767$,因此在这个地方随机数的取值范围过小了,因此可以选用一些更好的随机数生成器 mt_rand 。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    int n;
    map<int,bool> mp;
    
    int Find()
    {
        int l=0, r=1e9;
        while(l<r)
        {
            int mid=(l+r)/2;
            cout<<"> "<<mid<<endl;
            int x; cin>>x;
            if(x) l=mid+1;
            else r=mid;
        }
        return l;
    }
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
    
        cin>>n;
        int mx=Find();
    
        int d=0;
        mt19937 rnd(64708915);
        for(int i=1;i<=min(30,n);i++)
        {
            int idx;
            while(idx=rnd()%n+1)
            {
                if(mp.count(idx)) continue;
                mp[idx]=1;
                break;
            }
            cout<<"? "<<idx<<endl;
            int x; cin>>x;
            d=__gcd(d,mx-x);
        }
        cout<<"! "<<mx-(n-1)*d<<' '<<d<<endl;
    }
  • 相关阅读:
    解决IE8下VS2005,VS2008一些向导提示脚本错误问题
    12-7
    12.4
    写在十一月的尾巴
    11.28
    htm&css 颜色的浮动
    11.27
    11.26
    html基础——表格练习
    html基础——div/span
  • 原文地址:https://www.cnblogs.com/dilthey/p/10496803.html
Copyright © 2011-2022 走看看