CodeForces - 713B
交互题,你的程序提问,读入答案,然后接着提问,直到找到答案。
题意:一张n*n的棋盘,给两个矩形区域内的单元涂上了色,你需要每次询问一个矩形区域,然后对方会回答你在你询问的这个区域内是否包含一开始那两个矩形区域(回答的答案是0 or 1 or 2)。当且仅当矩形区域完全包含在询问的区域内时,才算包含。一个矩形区域用左下角(x1,y1)和右上角(x2,y2)来表示。你的询问不能超过200个。最后输出一开始那两个矩形区域的对角坐标
题解,对于x1、y1、x2、y2、x3、y3、x4、y4,分别做二分即可,很暴力。
简洁代码:
#include <bits/stdc++.h>
#define N 1000099
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int n;
#define LR(i) (i) & 1 ? R = mid - 1 : L = mid + 1
#define check(a, b, c, d, v, f, r, condition) \
{ \
int L = 1, R = r, mid, op; \
v = -1; \
while (L <= R) \
{ \
mid = (L + R) >> 1; \
printf("? %d %d %d %d\n", a, b, c, d); \
fflush(stdout); \
scanf("%d", &op); \
if (condition) op--; \
if (op) \
{ \
v = mid; \
LR(f); \
} \
else \
LR(f ^ 1); \
} \
}
int main()
{
cin >> n;
int y4, x4, y3, x3, y2, x2, x1, y1;
check(1, 1, n, mid, y2, 1, n, 0);
check(1, 1, mid, y2, x2, 1, n, 0);
check(1, mid, x2, y2, y1, 0, y2, 0);
check(mid, y1, x2, y2, x1, 0, x2, 0);
check(1, 1, n, mid, y4, 1, n, y2 <= mid);
check(1, 1, mid, y4, x4, 1, n, y2 <= y4 && x2 <= mid);
check(1, mid, x4, y4, y3, 0, y4, mid <= y1 && y2 <= y4 && x2 <= x4);
check(mid, y3, x4, y4, x3, 0, x4, y3 <= y1 && y2 <= y4 && mid <= x1 && x2 <= x4);
printf("! %d %d %d %d %d %d %d %d\n", x1, y1, x2, y2, x3, y3, x4, y4);
return 0;
}
一般代码:
#include <bits/stdc++.h>
#define N 1000099
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int n;
int main()
{
cin >> n;
int L = 1, R = n, mid, op;
int y2 = -1;
while (L <= R)
{
mid = (L + R) >> 1;
printf("? %d %d %d %d\n", 1, 1, n, mid);
fflush(stdout);
scanf("%d", &op);
if (op)
y2 = mid, R = mid - 1;
else
L = mid + 1;
}
L = 1, R = n;
int x2 = -1;
while (L <= R)
{
mid = (L + R) >> 1;
printf("? %d %d %d %d\n", 1, 1, mid, y2);
fflush(stdout);
scanf("%d", &op);
if (op)
x2 = mid, R = mid - 1;
else
L = mid + 1;
}
L = 1, R = y2;
int y1 = -1;
while (L <= R)
{
mid = (L + R) >> 1;
printf("? %d %d %d %d\n", 1, mid, x2, y2);
fflush(stdout);
scanf("%d", &op);
if (op)
y1 = mid, L = mid + 1;
else
R = mid - 1;
}
L = 1, R = x2;
int x1 = -1;
while (L <= R)
{
mid = (L + R) >> 1;
printf("? %d %d %d %d\n", mid, y1, x2, y2);
fflush(stdout);
scanf("%d", &op);
if (op)
x1 = mid, L = mid + 1;
else
R = mid - 1;
}
L = 1, R = n;
int y4 = -1;
while (L <= R)
{
mid = (L + R) >> 1;
printf("? %d %d %d %d\n", 1, 1, n, mid);
fflush(stdout);
scanf("%d", &op);
if (y2 <= mid) op--;
if (op)
y4 = mid, R = mid - 1;
else
L = mid + 1;
}
L = 1, R = n;
int x4 = -1;
while (L <= R)
{
mid = (L + R) >> 1;
printf("? %d %d %d %d\n", 1, 1, mid, y4);
fflush(stdout);
scanf("%d", &op);
if (y2 <= y4 && x2 <= mid) op--;
if (op)
x4 = mid, R = mid - 1;
else
L = mid + 1;
}
L = 1, R = y4;
int y3 = -1;
while (L <= R)
{
mid = (L + R) >> 1;
printf("? %d %d %d %d\n", 1, mid, x4, y4);
fflush(stdout);
scanf("%d", &op);
if (mid <= y1 && y2 <= y4 && x2 <= x4) op--;
if (op)
y3 = mid, L = mid + 1;
else
R = mid - 1;
}
L = 1, R = x4;
int x3 = -1;
while (L <= R)
{
mid = (L + R) >> 1;
printf("? %d %d %d %d\n", mid, y3, x4, y4);
fflush(stdout);
scanf("%d", &op);
if (y3 <= y1 && y2 <= y4 && mid <= x1 && x2 <= x4) op--;
if (op)
x3 = mid, L = mid + 1;
else
R = mid - 1;
}
printf("! %d %d %d %d %d %d %d %d\n", x1, y1, x2, y2, x3, y3, x4, y4);
return 0;
}