P2407 [SDOI2009] 地图复原 题解
考虑每行第一个出现的 T,在水平方向上一定是向右连路的,因为假如是向左而左边没有 T 的话……那岂不是要一直连到地图之外?
既然是向右连,那就只能连到下一个 T 然后转成竖直方向的了。那如果有第三个 T,还是只能向右连,连到第四个……以此类推,依次配对。
竖直方向同理,每一列的第一个和第二个 T 配对,第三个和第四个 T 配对……全部连上就得到了答案。
但是!直接一小段一小段连过去,似乎写起来还是有点麻烦呢?为了偷懒,再多想一步:水平方向上的一小段需要连路,当且仅当它正左侧的 T 数量为奇数;竖直方向上的一小段需要连路,当且仅当它正上方的 T 数量为奇数。所以,把所有的 T 当成 1,维护每一行、每一列的异或和即可,用 bitset 很好实现。输出时还可以用 "..."[...] 这个语法糖来偷偷懒。
\text{Code}
#include <bits/stdc++.h>
int main() {
int n, m;
std::cin >> n >> m;
std::bitset<1000> s, t;
while (n--) {
std::string str;
std::cin >> str;
for (int i = 0, a = 0; i < m; i++)
printf("o%c", "\n -"[(i != m - 1) + (a ^= t[i] = str[i] == 'T')]);
if (!n)
break;
s ^= t;
for (int i = 0; i < m; i++)
printf("%c%c", " |"[s[i]], " \n"[i == m - 1]);
}
}
PS:这题的代码目前已经被压到了 146B,如果发现了更短的写法请告诉我