砖块
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
思路:如果b 或者w 砖块的数量有一者的是0 表示不需要翻转
如果都是奇数个 则没有正确答案 参考第二个案例 无论怎么翻转 总有一个与众不同的砖块
需要翻转 砖块数量为偶数的 方便消除
先选择一个数量为偶数的砖块
可以从前到后 遍历每一个砖块 如果这砖块 则翻转此砖块和其后面的砖块 知道最后一行 次数一定会找到答案
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=210;
char s[N];
int T;
void turn(int n){
if(s[n]=='W')s[n]='B';
else s[n]='W';
if(s[n+1]=='B')s[n+1]='W';
else s[n+1]='B';
}
vector<int>num;
int main(){
cin>>T;
while(T--)
{
int w_c=0,b_c=0,n,cou=0;
cin>>n;
num.clear();
for(int i=0;i<n;i++){
cin>>s[i];
if(s[i]=='W')w_c++;
else b_c++;
}
// cout<<"w_c:"<<w_c;
// cout<<"b_c"<<b_c;
//如果其中一个为0 表示不需要翻转
if(w_c==0||b_c==0){cout<<0<<endl;continue;}
// cout<<'*';
//都为奇数也不需要翻转
if(w_c%2==1&&b_c%2==1){cout<<-1<<endl;continue;}
//翻转数量为偶数的
if(w_c%2==0){
for(int i=0;i<n-1;i++){
if(s[i]=='W')turn(i),cou++,num.push_back(i);
}
}else
{
for(int i=0;i<n;i++){
if(s[i]=='B')turn(i),cou++,num.push_back(i);
}
}
cout<<cou<<endl;
for(auto x:num)
{
cout<<x+1<<" ";
}
puts("");
}
}