acwing 砖块
题目
n 个砖块排成一排,从左到右编号依次为 1 ~ n。
每个砖块要么是黑色的,要么是白色的。
现在你可以进行以下操作若干次(可以是 0 次):
选择两个相邻的砖块,反转它们的颜色。(黑变白,白变黑)
你的目标是通过不超过 3n 次操作,将所有砖块的颜色变得一致。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
每组数据第一行包含一个整数 n。
第二行包含一个长度为 n 的字符串 s。其中的每个字符都是 W
或 B
,如果第 i 个字符是 W
,则表示第 i 号砖块是白色的,如果第 i 个字符是 B
,则表示第 i 个砖块是黑色的。
输出格式
每组数据,如果无解则输出一行 -1。
否则,首先输出一行 k,表示需要的操作次数。
如果 k>0,则还需再输出一行 k 个整数,p_1,p_2,…,p_k。其中 p_i 表示第 i 次操作,选中的砖块为 p_i 和 p_i+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
题解
分析
- 这道题目使目标字符串变为同一颜色,也就使只有两种情况
W/B
- 因为操作时,操作i会将i+1也操作,所以总操作次数为n-1次
- 如果不能变为全黑或全白 也就是check()函数,则输出-1
- 当全部操作完后,如果最后一项颜色与第一项颜色不相同,那么就是无法全变色
- swap函数用来更换值,其实也可以将swap(str[i+1])的功能也写入到swap函数里
代码
#include "string.h"
#include "iostream"
#include "vector"
using namespace std;
int n;
void swap(char &c){
if(c=='B')c='W';
else c='B';
}
bool check(string str,char c){
vector<int>tmp;
for(int i=0;i<n-1;i++){
if(str[i]!=c){
swap(str[i]);
swap(str[i+1]);
tmp.push_back(i);
}
}
if(str.front()!=str.back())return false;
else {
cout<<tmp.size()<<endl;
for(auto i:tmp)cout<<i+1<<' ';
if(tmp.size())cout<<endl;
return true;
}
}
int main(){
int T;
cin>>T;
string str;
while (T--){
cin>>n>>str;
if(!check(str,'B')&&!check(str,'W'))cout<<"-1"<<endl;
}
return 0;
}