Description

有两张n * m的图,一张上有一个红色四连通块,另一张上有一个蓝色四连通块,两张重叠在一起生成新图,规则是若某格既有红色又有蓝色便染成紫色,否则不染色。保证最边缘的一圈没有紫色格。现在给出新图,问红蓝染色的一种可行方案。

Hint

H, W <= 500

Sample Input

5 5 ..... .#.#. ..... .#.#. .....

Sample Output

..... ##### #.... ##### ..... .###. .#.#. .#.#. .#.#. .....

Solution

我们把除了第一行和最后一行的位置用红色和蓝色交替涂,列为奇数的涂红色,偶数的涂蓝色,然后在第一行全涂红色,最后一行全涂蓝色即可

Summary

构造题还是太弱了,开始思考的时候一直在想一种颜色横着搞,另一种颜色竖着搞,发现根本不能满足要求,然后一直在死磕怎么把已经涂过的路线绕开。。。 以后做这种构造题的时候思路还要更加开阔,不能只按照题目的要求去模拟,往往要跳出那个思维定势才能想到正确的做法

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
using namespace std;
const int Maxn = 500 + 100;
int A[Maxn][Maxn];
int N, M;
char safe_getchar()
{
char ch = getchar();
while (ch != '#' && ch != '.') ch = getchar();
return ch;
}
int main()
{
#ifdef hk_cnyali
freopen("C.in", "r", stdin);
freopen("C.out", "w", stdout);
#endif
scanf("%d%d", &N, &M);
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= M; ++j)
{
char c = safe_getchar();
if (c == '#') A[i][j] = 1;
}
for (int i = 1; i <= N; ++i)
{
for (int j = 1; j <= M; ++j)
if ((i == 1 || (j & 1) || A[i][j] == 1) && i != N)
cout<<"#";
else cout<<".";
cout<<endl;
}
cout<<endl;
for (int i = 1; i <= N; ++i)
{
for (int j = 1; j <= M; ++j)
if ((i == N || !(j & 1) || A[i][j] == 1) && i != 1)
cout<<"#";
else cout<<".";
cout<<endl;
}
return 0;
}