AcWing《蓝桥杯集训·每日一题》—— 3777. 砖块
本次博客我是通过Notion软件写的,转md文件可能不太美观,大家可以去我的博客中查看:北天的 BLOG,持续更新中,另外这是我创建的编程学习小组频道,想一起学习的朋友可以一起!!!
一、题目
每个砖块要么是黑色的,要么是白色的。
现在你可以进行以下操作若干次(可以是 0 次):
选择两个相邻的砖块,反转它们的颜色。(黑变白,白变黑)
你的目标是通过不超过 3 n 3n 3n 次操作,将所有砖块的颜色变得一致。
输入格式
第一行包含整数 T T T,表示共有 T T T 组测试数据。
每组数据第一行包含一个整数 n n n。
第二行包含一个长度为 n n n 的字符串 s s s。其中的每个字符都是 W
或 B
,如果第 i i i 个字符是 W
,则表示第 i i i 号砖块是白色的,如果第 i i i 个字符是 B
,则表示第 i i i 个砖块是黑色的。
输出格式
每组数据,如果无解则输出一行 −1。
否则,首先输出一行 k k k,表示需要的操作次数。
如果 k > 0 k>0 k>0,则还需再输出一行 k k k 个整数, p 1 , p 2 , … , p k p1,p2,…,pk p1,p2,…,pk。其中 p i p_i pi 表示第 i i i 次操作,选中的砖块为 p i p_i pi 和 p i + 1 p_i+1 pi+1 号砖块。
如果方案不唯一,则输出任意合理方案即可。
数据范围
1 ≤ T ≤ 10 1≤T≤10 1≤T≤10,
2 ≤ n ≤ 200 2≤n≤200 2≤n≤200。
输入样例:
4
8
BWWWWWWB
4
BWBB
5
WWWWW
3
BWB
输出样例:
3
6 2 4
-1
0
2
2 1
二、解题思路
这道题目需要我们实现的是对给定字符串s进行操作,使得其变成一个全为’B’或全为’W’的字符串,并输出操作次数以及具体的操作。操作规则为,如果s中’B’和’W’个数均为偶数,则不需要进行任何操作;如果’B’个数为奇数,需要对相邻的两个’B’进行操作,使其变成’W’,或者将’B’和’W’对调,使得’B’个数变为偶数,然后进行相邻的’B’操作,使其变成’W’。如果’W’个数为奇数,操作方法与’B’个数奇数的情况相似。
具体来说,我们在实现的过程是先计算’B’和’W’的个数,然后根据个数的奇偶性进行分类讨论。当’B’和’W’的个数均为偶数时,不需要操作。当其中一个为奇数时,需要对相邻的两个颜色相同的块进行操作,使其变成相反的颜色,或者将两个不同颜色的块进行对调,使得颜色个数为偶数。通过循环操作后,最终得到一个全为’B’或者全为’W’的字符串。最后输出操作次数和具体操作的序列。
三、解题思路
# 输入测试用例数量
T = int(input())
for _ in range(T):
# 输入字符串长度和字符串
n = int(input())
s = list(input())
# 统计W和B的数量
w_cnt = s.count('W')
b_cnt = s.count('B')
# 判断是否有解
if w_cnt % 2 == 1 and b_cnt % 2 == 1:
print(-1) # 没有解
else:
res_cnt = 0 # 记录需要操作的次数
res = [] # 记录操作的位置
if w_cnt % 2 == 1: # W的数量为奇数,需要将一些B变成W
i = 0
while i < n - 1:
if s[i] == 'B' and s[i+1] == 'B': # 连续的两个B都变成W
s[i] = 'W'
s[i+1] = 'W'
res_cnt += 1
res.append(i + 1)
i += 2
elif s[i] == 'B' and s[i+1] == 'W': # 只将前面的B变成W
s[i] = 'W'
s[i+1] = 'B'
res_cnt += 1
res.append(i + 1)
i += 1
elif s[i] == 'W': # 如果是W则不用操作
i += 1
else: # B的数量为奇数,需要将一些W变成B
i = 0
while i < n - 1:
if s[i] == 'W' and s[i+1] == 'W': # 连续的两个W都变成B
s[i] = 'B'
s[i+1] = 'B'
res_cnt += 1
res.append(i + 1)
i += 2
elif s[i] == 'W' and s[i+1] == 'B': # 只将前面的W变成B
s[i] = 'B'
s[i+1] = 'W'
res_cnt += 1
res.append(i + 1)
i += 1
elif s[i] == 'B': # 如果是B则不用操作
i += 1
# 输出结果
if res_cnt > 0:
print(res_cnt)
for x in res:
print(x, end = ' ')
print()
else:
print(0)
这段代码的时间复杂度为 O ( T n ) O(Tn) O(Tn),其中 T T T是测试用例的数量, n n n是输入字符串的长度。这是因为代码中有一个外层循环,循环 T T T次,而每次循环中都要对长度为 n n n的输入字符串进行遍历,所以总时间复杂度是 O ( T n ) O(Tn) O(Tn)。
在代码中,使用了一些内置函数和操作,如**s.count()
和s[i]
**等,这些操作的时间复杂度较低,可以忽略不计。因此,这段代码的主要瓶颈在于对输入字符串的遍历和修改操作。
如果要优化这段代码的时间复杂度,可能需要重新设计算法。可以考虑一些贪心策略,如将相邻的不同颜色的棋子互换,使得相邻的棋子颜色相同。这样可以尽可能地减少需要修改的棋子数量。但这个算法的正确性需要进行证明,同时实现也可能会比较复杂。
转载:https://blog.csdn.net/qq_52417436/article/details/129095282