1. 问题描述:
n 个砖块排成一排,从左到右编号依次为 1∼n。每个砖块要么是黑色的,要么是白色的。现在你可以进行以下操作若干次(可以是 0 次):选择两个相邻的砖块,反转它们的颜色。(黑变白,白变黑)你的目标是通过不超过 3n 次操作,将所有砖块的颜色变得一致。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。每组数据第一行包含一个整数 n。第二行包含一个长度为 n 的字符串 s。其中的每个字符都是 W 或 B,如果第 i 个字符是 W,则表示第 i 号砖块是白色的,如果第 i 个字符是 B,则表示第 i 个砖块是黑色的。
输出格式
每组数据,如果无解则输出一行 −1。否则,首先输出一行 k,表示需要的操作次数。如果 k>0,则还需再输出一行 k 个整数,p1,p2,…,pk。其中 pi 表示第 i 次操作,选中的砖块为 pi 和 pi+1 号砖块。如果方案不唯一,则输出任意合理方案即可。
数据范围
1 ≤ T ≤ 10,
2 ≤ n ≤ 200。
输入样例:
4
8
BWWWWWWB
4
BWBB
5
WWWWW
3
BWB
输出样例:
3
6 2 4
-1
0
2
2 1
来源:https://www.acwing.com/problem/content/description/3780/
2. 思路分析:
这道题目与95题是很类似的,95题其实是一维版本的扩展(二维版本),这道题目其实是一维版本,不管是一维版本还是二维版本思路都是类似的,都可以使用递推来解决,由题目可知我们只要输出任意一种合法的方法即可,所以我们可以尝试将所有的字符变为"W"或者变为"B",只要存在一种合理的方法则输出对应的操作序列,因为第一个字符是确定的,所以要想将所有字符变为"B"或者"W"那么从第一个字符开始递推得到其余的字符即可,第一个字符是唯一确定的所以对于之后的每一个字符的操作序列都是确定的,当我们递推到最后一个字符的时候判断与第一个字符是否相等即可,如果相等说明符合要求。
3. 代码如下:
from typing import List
class Solution:
def update(self, s: List[str], i: int):
if s[i] == "W":
s[i] = "B"
else:
s[i] = "W"
def check(self, s: str, t: str):
# 将其转换为列表这样才可以进行修改
s = list(s)
# 存储操作序列
res = list()
for i in range(len(s) - 1):
c = s[i]
if c != t:
# 说明当前字符需要修改, 并且添加操作序列
res.append(i)
# 修改当前字符为另外一个字符
self.update(s, i)
self.update(s, i + 1)
# 判断首尾字符是否相同
if s[0] != s[-1]: return False
print(len(res))
# 注意是从1开始编号的
for x in res: print(x + 1, end=" ")
# res有操作序列的时候才输出换行
if len(res): print()
return True
def process(self):
T = int(input())
for i in range(T):
n = int(input())
s = input()
# 变成"B"和"W"都不可以那么输出-1
if not self.check(s, "W") and not self.check(s, "B"):
print(-1)
if __name__ == '__main__':
Solution().process()