CodeForces 1063C. Dwarves, Hats and Extrasensory Abilities 交互
题目大意:
依次给定$n$个点的颜色,要求给定这$n$个点的坐标以及一条可以把他们分成两部分的直线
强制在线(交互)
$n \leqslant 30$
感觉自己真像一个乱搞...
我们只考虑把点放在最长的斜线$y = x$上
考虑$[0, 2^2]$,如果我们把第一个点放在$(0, 0)$上,那么后面根据返回的颜色是否与第一个点相同去二分,能放$3$个点
所以我们只需要$[0, 2^{29}]$就能放下30个点了
但是最后的白点和黑点的坐标差距只有$1$
这个时候,我们选取$y = -x + b \to x + y = b$
将$x, y$同时增加和减少0.5时,我们就能得到一个很不错的分割线
注意直线的端点一定要落在$[0, 10^9]$内,做了一些处理
连交互格式都不会的蒟蒻...
#include <queue> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm>
using namespace std;
char s[1005]; int l, r = 1 << 29; int flag, lst, n, lp; inline char out(int x, int y) { lp = x + 5000; cout << x + 5000 << " " << y + 5000 << endl; fflush(stdout); cin >> s; return s[0]; } inline void gz(int o) { int p1 = o / 2 - 1; int p2 = o / 2 - 2; cout << p1 << " " << o - p1 << " "; cout << p2 << " " << o - p2 << endl; fflush(stdout); } int main() { cin >> n; n --; flag = out(0, 0); while(n --) { int mid = (l + r) >> 1; if(out(mid, mid) == flag) l = mid, lst = 1; else r = mid, lst = 0; } if(lst) gz(lp * 2 + 1); else gz(lp * 2 - 1); return 0; }
喵喵喵?喵喵喵! 喵喵喵......