CF1917E Construct Matrix TJ
E_Construct_Matrix题解
题面
Luogu
Codeforces
思路
考虑分块,把大矩阵分成多个分块矩阵。
我们容易构造出:
考虑到
当
例如
当
举例
若构造:
但似乎不优,可以更充分地使用空间。
若构造:
我们分块出左上角
构造了贡献
至此,包括
若使用贡献
至此,我们实际已构造出
剩下的情况是否无解呢?
事实上,除了特例
证明:
若:
设
因为题设,则有
又因为每一行的异或值相同。
所以
又
所以
所以此题中
至此,我们讨论出了所有情况。
CODE
#include <bits/stdc++.h>
#define int long long
using namespace std;
using ll = long long;
const int _ = 2e3 + 7;
// data:
bool c[_][_];
// function:
signed main() {
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T;
cin >> T;
while (T--) {
memset(c, 0, sizeof c);
int n, k;
cin >> n >> k;
if (k & 1) {
cout << "No\n";
} else {
if (k % 4 == 0) {
cout << "Yes\n";
for (int i = 1; i <= n / 2; i++) {
for (int j = 1; j <= n / 2; j++) {
if (k > 0) {
c[2 * i][2 * j] = c[2 * i][2 * j - 1] = c[2 * i - 1][2 * j] = c[2 * i - 1][2 * j - 1] = 1;
k -= 4;
} else {
break;
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << c[i][j] << ' ';
}
cout << '\n';
}
} else {
if (n == 2) {
cout << "Yes\n";
cout << "1 0\n0 1\n";
continue;
}
if (k == 2 || k == n * n - 2) {
cout << "No\n";
continue;
}
cout << "Yes\n";
for (int i = 1; i <= n / 2; i++) {
for (int j = 1; j <= n / 2; j++) {
if ((i == 1 && j == 1) || (i == 1 && j == 2) || (i == 2 && j == 1) || (i == 2 && j == 2)) continue;
if (k > 0) {
if (k == 6 || k == 10) break;
c[2 * i][2 * j] = c[2 * i][2 * j - 1] = c[2 * i - 1][2 * j] = c[2 * i - 1][2 * j - 1] = 1;
k -= 4;
} else {
break;
}
}
}
c[1][1] = c[1][2] = c[2][1] = c[2][3] = c[3][2] = c[3][3] = 1; // if(k == 6). k must be 6 or 10
if (k == 10)
c[3][1] = c[4][1] = c[3][4] = c[4][4] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << c[i][j] << ' ';
}
cout << '\n';
}
}
}
}
return 0;
}
// submit by Acerkaio.