n个菜, 编号从1-n, 其中有k个菜被点了, 你每次可以猜x, y两个数字, 如果|x-a|<=|y-b|
交互器会返回"TAK"
, 否则返回"NIE"
, 其中a是离x最近的一个被点过的菜的编号, a可以等于x, b同理
要求在60次内猜出任意两个被点了的菜
n<=1e5
60次以内猜出, 肯定是logn级别的复杂度, 也就是二分
交互器返回的答案只能判断x和y离他们最近的点过的菜的距离哪个更小, 那么输出两个相邻的数字, mid和mid+1, 如果mid距离更近, 那么[1, mid]肯定有一个被点过的菜, 反之[mid+1, n]肯定有一个被点过的菜, 这样用二分的思想一直分割下去一定能的到一个位置x
因为有两个以上被点过的菜, 所以[1, x-1], [x+1, n]这两个区间中至少有一个菜, 同样的做法找到另一个
#include
using namespace std;
const int MANX = 1E5 + 100;
int n, k;
char s[100];
bool query(int x, int y)
{
printf("1 %d %d\n", x, y);
cout.flush();
scanf("%s", s);
return s[0] == 'T';
}
int bs(int l, int r)
{
if(l>r) return -1;
int mid;
while(l < r)
{
mid = (l+r)/2;
if(query(mid, mid+1)) r = mid;
else l = mid+1;
}
return l;
}
int main()
{
scanf("%d%d", &n, &k);
int x = bs(1, n), y;
if(x==1) y = bs(x+1, n);
else if(x==n) y = bs(1, x-1);
else
{
y = bs(1, x-1);
if(!query(y, x)) y = bs(x+1, n);
}
printf("2 %d %d\n", x, y);
return 0;
}