CF.810D.Glad to see you!(交互 二分)
阿新 • • 發佈:2018-07-28
http 一個數 spa force .com fine ctype test read 次可以確定一個數\(A\)。
對於第二個數,可以在\([1,A-1]\)和\([A+1,n]\)中分別二分。
題目鏈接
\(Description\)
有一個大小為\(k\)的集合\(S\),元素兩兩不同且在\([1,n]\)內。你可以詢問不超過\(60\)次,每次詢問你給出\(x,y\),交互庫會返回\(\left[\ \min(|x-a|,a\in S)\leq \min(|y-a|,a\in S)\ \right]\)是(TAK)否(NIE)為真。求任意兩個一定在集合\(S\)中出現過的數。
\(Solution\)
考慮對區間\([l,r]\)二分,若Check(mid,mid+1)==1,則區間\([1,mid]\)中一定存在一個數;否則區間\([mid+1,r]\)中一定存在一個數。這樣用\(\log10^5=16\)
對於第二個數,可以在\([1,A-1]\)和\([A+1,n]\)中分別二分。
#include <cstdio> #include <cctype> #define gc() getchar() const int N=1e5+5; int n; inline int read() { int now=0;register char c=gc(); for(;!isdigit(c);c=gc()); for(;isdigit(c);now=now*10+c-'0',c=gc()); return now; } inline bool Query(int x,int y) { static char s[7]; if(y>n) return 1;//! printf("1 %d %d\n",x,y); fflush(stdout); return scanf("%s",s),s[0]=='T'; } int Check(int l,int r) { if(l>r) return 0; int mid,ans=0; while(l<=r) if(mid=l+r>>1, Query(mid,mid+1)) ans=mid,r=mid-1; else l=mid+1; return ans; } int main() { n=read(); int K=read(); int A=Check(1,n), B=Check(1,A-1); if(!B) B=Check(A+1,n); printf("2 %d %d\n",A,B); fflush(stdout); return 0; }
CF.810D.Glad to see you!(交互 二分)