1 条题解

  • 0
    @ 2022-3-24 20:33:39

    交互题。认真读题。

    给定 nn,要求你构造(注意)一个 n×nn \times n 的矩阵,其中的元素 ai,j[0,1016]a_{i,j} \in [0,10^16]

    输出这个矩阵后会给你 qq 次询问,每次询问给出一条 (1,1)(1,1)(n,n)(n,n) 路径(只能向下或右)上所有元素的和,要求你输出这条路径。你的路径与答案不相同即会 WA,这意味着路径是唯一的。

    1n251 \le n \le 250ai,j10160 \le a_{i,j} \le 10^{16}

    让你构造一个矩阵没有两条路径值相同,显然构造题,容易想到和二进制有关。

    注意到 101625010^{16} \approx 2^{50},走过的点的数量 2n1<502n-1 < 50,诶,对上了,有戏。

    考虑将用二进制第 xx 位表示经过时第 xx 个点是向下还是向右了。

    这样的话,就要保证向下和向右一个是 00, 一个是 2x2^x。所以对于所有 i+j=xi+j=x,即所有可能在第 xx 步经过的点,一条对角线,让 002x2^x 交替出现即可。(以上可能有加一减一的问题。)

    比如 n=4n=4 时的一个矩阵:

    0  0  0   0
    2  4  8   0
    0  0  16  0
    8  0  32  0
    
    CODE
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
     
    inline int read() {
        int x = 0, f = 0; char c = 0;
        while (!isdigit(c)) f |= c == '-', c = getchar();
        while (isdigit(c)) x = (x << 3) + (x << 1) + (c & 15), c = getchar();
        return f ? -x : x;
    }
     
    #define N 110
     
    int n, s[N], a[N][N];
     
    signed main() {
        int n = read();
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j ++) {
                int x = i + j;
                a[i][j] = (s[x] ++ & 1ll) << x - 2;
            }
        }
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j ++) {
                printf("%lld ", a[i][j]);
            } 
            puts(""), fflush(stdout);
        }
        for (int T = read(); T --;) {
            int s = read(), x = 1, y = 1;
            while (x != n || y != n) {
                printf("%lld %lld\n", x, y), fflush(stdout);
                int st = s & (1ll << (x + y - 1ll));
                (st == a[x + 1][y] && x < n) ? x ++ : y ++;
            }
            printf("%lld %lld\n", x, y), fflush(stdout);
        }
        return 0;
    }
    

    TIP

    使用位运算时别忘了 1ll,这两天被坑了几次了 。

    • 1

    信息

    ID
    802
    时间
    2000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    6
    已通过
    1
    上传者