「解题报告」ARC140E Not Equal Rectangle

很神奇的构造题,我瞎构造一通然后出来了。

首先观察数据范围,\(n\le 500\)\(25\) 大概是根号级别的。所以我们考虑构造 \(B \times B\)\(B \times B\) 的矩形拼接在一起。

我们先考虑固定住一行矩形,然后下面每一行都由第一行值域平移而来。这样我们要构造的这一行矩形需要满足的条件就是:不存在 \(x_1, x_2, y_1, y_2\),满足 \(a_{x_1,y_1} = a_{x_1, y_2}\)\(a_{x_2, y_1} = a_{x_2, y_2}\)。(因为值域平移了 \(B\) 次,所以每一行的数是啥不重要,肯定都会出现一次,只需要这一行两个数相等即可)

那么我们可以考虑先选出来两个相等的数(以 \(1\) 举例),那么接下来我们需要满足这两个数所在的两列数只有 \(1\) 是相同的,其它都不相同。考虑裴蜀定理,我们可以令每一列数为一个等差数列,对于从左到右第 \(i\) 个矩形(从 \(0\) 开始),第 \(j\) 列为首项为 \(j\),公差为 \(i\) 的数列。这样就能满足每两列只有一个数字相同了。

那么我们只需要选取一个质数 \(B\) 即可。发现 \(23^2 = 529 > 500\),所以选取 \(B=23\) 即可。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 605;
int n, m;
int a[MAXN][MAXN];
int B = 23;
int main() {
    for (int i = 1; i <= B; i++) {
        for (int j = 1; j <= B; j++) {
            for (int k = 1; k <= B; k++) {
                a[k][(i - 1) * B + j] = ((j - (i - 1) * (k - 1) - 1) % B + B) % B + 1;
            }
        }
    }
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        int off = (i - 1) / B, row = (i - 1) % B + 1;
        for (int j = 1; j <= m; j++) {
            printf("%d ", (a[row][j] + off - 1) % B + 1);
        }
        printf("\n");
    }
    return 0;
}
posted @ 2023-01-20 17:07  APJifengc  阅读(65)  评论(10编辑  收藏  举报