CodeForces 1917E Construct Matrix
\(2 \nmid k\) 显然无解。
若 \(4 \mid k\),发现给一个全 \(2 \times 2\) 子矩形全部异或 \(1\) 不会对行异或和和列异或和造成影响。那么我们找到 \(\frac{k}{4}\) 个全 \(0\) 的 \(2 \times 2\) 子矩形填 \(1\) 即可。
否则若 \(k = 2\) 或 \(k = n^2 - 2\),除 \(n = 2\) 外无解。
否则我们有一个 \(k = 6\) 的构造,即令 \(a_{1, 1} = a_{1, 2} = a_{2, 1} = a_{2, 3} = a_{3, 2} = a_{3, 3} = 1\)。
若 \(k\) 更大,把左上角的 \(4 \times 4\) 矩形抠掉后再找 \(2 \times 2\) 全 \(0\) 矩形,全部填 \(1\)。
若 \(k\) 还有剩余,在左上角 \(4 \times 4\) 矩形中找和为 \(1\) 的 \(2 \times 2\) 子矩形,全部异或上 \(1\),可以使得这个子矩形的和变为 \(3\)。重复这样找直到 \(k\) 被消耗尽即可。容易发现一定能找到这样的子矩形。
code
// Problem: E. Construct Matrix
// Contest: Codeforces - Codeforces Round 917 (Div. 2)
// URL: https://codeforces.com/contest/1917/problem/E
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;
const int maxn = 1010;
int n, m, a[maxn][maxn];
void solve() {
scanf("%d%d", &n, &m);
if (m & 1) {
puts("No");
return;
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
a[i][j] = 0;
}
}
if (m % 4 == 0) {
for (int i = 1; i < n && m; i += 2) {
for (int j = 1; j < n && m; j += 2) {
a[i][j] = a[i + 1][j] = a[i][j + 1] = a[i + 1][j + 1] = 1;
m -= 4;
}
}
} else {
if (n == 2) {
puts("Yes\n1 0\n0 1");
return;
}
if (m == 2 || m == n * n - 2) {
puts("No");
return;
}
a[1][1] = a[1][2] = a[2][1] = a[2][3] = a[3][2] = a[3][3] = 1;
m -= 6;
for (int i = 1; i < n && m; i += 2) {
for (int j = 1; j < n && m; j += 2) {
if (i < 4 && j < 4) {
continue;
}
a[i][j] = a[i + 1][j] = a[i][j + 1] = a[i + 1][j + 1] = 1;
m -= 4;
}
}
while (m) {
bool fl = 1;
for (int i = 1; i < 4 && fl; i += 2) {
for (int j = 1; j < 4 && fl; j += 2) {
if (a[i][j] + a[i + 1][j] + a[i][j + 1] + a[i + 1][j + 1] == 1) {
a[i][j] ^= 1;
a[i + 1][j] ^= 1;
a[i][j + 1] ^= 1;
a[i + 1][j + 1] ^= 1;
m -= 2;
fl = 0;
}
}
}
}
}
puts("Yes");
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
printf("%d ", a[i][j]);
}
putchar('\n');
}
}
int main() {
int T = 1;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}