codeforces 810 D. Glad to see you!
http://codeforces.com/contest/810/problem/D
题意
大小为k的集合,元素的范围都在[1,n],每次可以询问(x,y),如果min|x-a|<=min|y-b| a,b∈S,交互库返回”TAK",否则返回“NIE”。
分析
怎么确保能找到答案。我们可以将(1~n)分成两份(1~mid)(mid+1~r),显然要猜的数肯定是在这两个区间内。
然后怎么判断我们可以找mid和mid+1两个数来判断,如果|mid-a|<=|mid+1-b|,那么显然要猜的数肯定是mid或者mid的左侧。如果|mid-a|>|mid+1-b|很显然要猜的数肯定是mid+1或者mid+1的右侧然后就是二分,根据题目的回答进行二分
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<cctype> 7 #include<set> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 using namespace std; 12 typedef long long LL; 13 14 int n,k; 15 char s[10]; 16 17 bool Ask(int x,int y) { 18 if (y > n) return true; 19 printf("1 %d %d ",x,y); fflush(stdout); 20 scanf("%s",s); 21 return s[0] == 'T'; 22 } 23 int check(int L,int R) { 24 if (L > R) return 0; 25 int ans = 0; 26 while (L <= R) { 27 int mid = (L + R) >> 1; 28 if (Ask(mid, mid + 1)) ans = mid, R = mid - 1; 29 else L = mid + 1; 30 } 31 return ans; 32 } 33 int main() { 34 cin >> n >> k; 35 int A = check(1, n), B; 36 B = check(1, A - 1); 37 if (!B) B = check(A + 1, n); 38 printf("2 %d %d", A, B); fflush(stdout); 39 return 0; 40 }