CodeForces - 713B

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值