这是一道不错的贪心题目,同时也考察了选手们的读题仔细程度。先给出几个关键点:

  1. 只能对两个相邻且均为白色的格子进行染色,也就是说染色是不能够覆盖的

  2. 对于输入中的 1 的位置一定要为红色,其余位置随意。

以某行的第 $i$ 列 ($1 \le i \le n$)为基准,若所在的两个格子均存在,则有可能的三种染法:

  1. $p_i$ 与 $q_i$
  2. $p/q_i$ 与 $p/q_{i - 1}$
  3. $p/q_i$ 与 $p/q_{i + 1}$

这其中有一个贪心的顺序,若调换可能会出现错误。想要去进行最优的染色一定是按照 $2\to 1 \to 3$ 的顺序才能充分利用所有的白色格子。想通这个后,接下去就是一些细节的实现了。

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
n = read ();
scanf ("%s%s",da,db);
ok = 1;
for(register int i = 0;i <= n;++i) ca[i] = cb[i] = 0;//注意一下,不要用 memset 会超时哦
//0 white 1 red 2 blue
for (register int i = 0;i < n;++i)
{
if (da[i] == '1')//第一行的第 i 块需要被染色
{
if (ca[i] == 1) ;//已经被染成目标色
//注意要两个格子均存在且均为白色才能染
else if (!ca[i - 1] && !ca[i] && i >= 1) ca[i - 1] = 2,ca[i] = 1;//2
else if (!ca[i] && !cb[i] && db[i] == '0') ca[i] = 1,cb[i] = 2;//1,这里要注意若两行均为 1 则不能进行此操作,否则不是最优方法/无法成功染色
else if (!ca[i + 1] && !ca[i] && da[i + 1] == '0' && i < n - 1) ca[i] = 1,ca[i + 1] = 2;//3
else {ok = 0;break;}//无法实现
}
if (db[i] == '1')//第二行的第 i 块需要被染色
{
if (cb[i] == 1) ;
else if (!cb[i - 1] && !cb[i] && i >= 1) cb[i - 1] = 2,cb[i] = 1;
else if (!ca[i] && !cb[i] && da[i] == '0') ca[i] = 2,cb[i] = 1;
else if (!cb[i + 1] && !cb[i] && db[i + 1] == '0' && i < n - 1) cb[i] = 1,cb[i + 1] = 2;
else {ok = 0;break;}
}
}
if (ok) printf ("RP\n");
else printf ("++\n");