CS 300 Second Minimum 交互题,思维(循环赛)

来源:互联网 发布:济南行知小学位置 编辑:程序博客网 时间:2024/05/18 11:01
CS 300
题意:交互题,电脑藏了一个[1..n]的排列.每次的询问:问两个下标(i,j),哪一个对应值较小.
n<=1e4,询问次数不超过min(2n,n+15)时.求出val=2对应的下标是多少?

容易用n-1次比较求出最小值val=1的下标.

类似循环赛淘汰,线段树求最值 通过询问最底层n次 知道最小值和被最小值淘汰的logn个元素.第二小的肯定在这logn个元素内.

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e4+5,mod=1e9+7;int n;vector<int> v[N];int query(int i,int j){    printf("Q %d %d\n",i,j);    fflush(stdout);    int x;    scanf("%d",&x);    return x==i;}int solve(int le,int rg){    if(le==rg)        return le;    int m=le+rg>>1;    int a=solve(le,m),b=solve(m+1,rg);    if(query(a,b))    {        v[a].push_back(b);        return a;    }    else    {        v[b].push_back(a);        return b;    }}int main(){    scanf("%d",&n);    int a=solve(1,n);    int b=v[a][0];    for(int i=1;i<v[a].size();i++)    {        if(query(v[a][i],b))            b=v[a][i];    }    printf("A %d\n",b);    fflush(stdout);    return 0;}