原题题面
题目描述
现在给你一个 矩阵 ,要求构造两个 矩阵 ,满足在矩阵 中的所有 均出现在 中,且 中 的交集为 中所有的 。同时 中所有的 有一种联通的状态(联通:所有的 的上下左右四个方向至少有一个相邻的 。)
数据格式
输入样例
5 5
00000
00100
01010
01100
00000
输出样例
00000
00100
01110
01100
00000
00000
01110
01010
01110
00000
题目分析
这是一道 构造题 。
注意 矩阵的最外围一圈都是 ,这是一个关键信息也是一个提示。
在 vp 时,我们构造了很多方式都没有成功,甚至一度尝试 dfs 进行搜素路径。
赛后看题解,发现这是一个非常巧妙的构造。其主要思想是按行或列的奇偶进行填 ,并利用相对的边界进行连结。
例如,我们将 中除第一行和最后一行的其他行的所有的奇数列全部填 ,所有的偶数行与 中一致,同时将第一行全部填 。将 中除第一行和最后一行的其他行的所有偶数列全部填 ,所有的奇数行与 中一致,同时将最后一行全部填 。可以发现这样的构造可以保证 中的 是联通的,并且 中 的交集一定是 中的 而不会产生多余的 ,因为在 中除 中的 之外的 没有重复。
Accept代码
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
char c[N][N];
int main()
{
ios::sycn_with_stdio(flase);
cin.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i ++) cin >> c[i] + 1;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
{
if (i < n && (i == 1 || j % 2 == 1 || c[i][j] == '1')) cout << 1;
else cout << 0;
if (j == m) cout << "\n";
}
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
{
if (i > 1 && (i == n || j % 2 == 0 || c[i][j] == '1')) cout << 1;
else cout << 0;
if (j == m) cout << "\n";
}
return 0;
}