话不多说直接上题目!!
一、题目
点击下面啦!
砖块
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
注意!答案不唯一,那么我们直接看例子!还有就是两个相邻的字母都改变!今天我们用O(1)复杂度来解决这个简单问题!
二、思路
1.
目标是通过不超过 3n 次操作,将所有砖块的颜色变得一致。
我们先设置两个变量cntb,和cntw分别表示字符串中字母为’B’的个数,和字符串中字母为’W’的个数。
先来看第一个例子,我们可以看出cntb和cntw都为偶数,并且我们可以发现无论把结果变成全为”B“还是”W“都为正确答案!
if (cntb % 2 == 0 && cntw % 2 == 0) {
for (int i = 1; i < len; i++)
{
if (a[i] != a[0]) {
if (a[i + 1] == 'B')a[i + 1] = 'W';
else a[i + 1] = 'B';
q.push(i+1);
}
}
cout << q.size() << endl;
while (!q.empty()) {
cout << q.front() << " "; q.pop();
}
cout << endl;
continue;
}
再看第二个例子,我们看出cntb和cntw都为奇数,我们可以举出例子,当cntb和cntw都为奇数的时候,答案其实是无解的:
eg:BWWW变成BBBW无解,BBBWWW变成BBBBBW也无解,因为最终改变的结果有一个单独的字母,所以我们可以得到字母都为奇数的情况下无解
if (cntw % 2 == 1 && cntb % 2 == 1) {
cout << -1 << endl; continue;
}
第三个例子,那就是cntb和cntw有一个为0,也就是本来就是同色,直接输出0即可!
if (cntw == 0 || cntb == 0) {
cout << 0 << endl; continue;
}
第四个例子,那就是cntb和cntw有一个为偶数,一个为奇数。由第二个例子可以得出,在第二个例子最后的改变中,再加一个可以改变的字母,结果就能全部变成同色!
eg:BWW变成BBB,BBWWW变成WWWWW
而且不能发现只能改变成字母数为奇数的那个字母!
在这里分两种,一种是cntb为奇数,另一种是cntw为奇数
if (cntw % 2 == 1) {
for (int i = 0; i < len; i++)
{
if (a[i] == 'B') {
q.push(i+1);
if (a[i + 1] == 'W')a[i + 1] = 'B';
else a[i + 1] = 'W';
}
}
cout << q.size() << endl;
while (!q.empty()) {
cout << q.front() << " "; q.pop();
}
cout << endl;
continue;
}
if (cntb % 2 == 1) {
for (int i = 0; i < len; i++)
{
if (a[i] == 'W') {
p.push(i+1);
if (a[i + 1] == 'W')a[i + 1] = 'B';
else a[i + 1] = 'W';
}
}
cout << p.size() << endl;
while (!p.empty()) {
cout << p.front() << " "; p.pop();
}
cout << endl;
continue;
}
代码
不难发现我们用规律的方式也可以写出这道题,我看了一下其他人用dp做的,可能我dp学的不太行吧,嘻嘻本人蒟蒻!
using namespace std;
int t, n;
int main()
{
cin >> t;
while (t--)
{
cin >> n;
string a;
cin >> a;
queue<int> q,p;
int cntw = 0, cntb = 0;
int len = a.length();
for (int i = 0; i < len; i++)
{
if (a[i] == 'W')cntw++; else cntb++;
}
if (cntw % 2 == 1 && cntb % 2 == 1) {
cout << -1 << endl; continue;
}
else if (cntw == 0 || cntb == 0) {
cout << 0 << endl; continue;
}
if (cntw % 2 == 1) {
for (int i = 0; i < len; i++)
{
if (a[i] == 'B') {
q.push(i+1);
if (a[i + 1] == 'W')a[i + 1] = 'B';
else a[i + 1] = 'W';
}
}
cout << q.size() << endl;
while (!q.empty()) {
cout << q.front() << " "; q.pop();
}
cout << endl;
continue;
}
if (cntb % 2 == 1) {
for (int i = 0; i < len; i++)
{
if (a[i] == 'W') {
p.push(i+1);
if (a[i + 1] == 'W')a[i + 1] = 'B';
else a[i + 1] = 'W';
}
}
cout << p.size() << endl;
while (!p.empty()) {
cout << p.front() << " "; p.pop();
}
cout << endl;
continue;
}
if (cntb % 2 == 0 && cntw % 2 == 0) {
for (int i = 1; i < len; i++)
{
if (a[i] != a[0]) {
if (a[i + 1] == 'B')a[i + 1] = 'W';
else a[i + 1] = 'B';
q.push(i+1);
}
}
cout << q.size() << endl;
while (!q.empty()) {
cout << q.front() << " "; q.pop();
}
cout << endl;
continue;
}
}
}