[Codeforces #608 div2]1272B Blocks

Description

There are n n n blocks arranged in a row and numbered from left to right, starting from one. Each block is either black or white.

You may perform the following operation zero or more times: choose two adjacent blocks and invert their colors (white block becomes black, and vice versa).

You want to find a sequence of operations, such that they make all the blocks having the same color. You don’t have to minimize the number of operations, but it should not exceed 3 ⋅ n 3⋅n 3n. If it is impossible to find such a sequence of operations, you need to report it.

Input

The first line contains one integer n ( 2 ≤ n ≤ 200 ) n(2≤n≤200) n(2n200) — the number of blocks.

The second line contains one string s consisting of n characters, each character is either “W” or “B”. If the i-th character is “W”, then the i-th block is white. If the i-th character is “B”, then the i-th block is black.

Output

If it is impossible to make all the blocks having the same color, print − 1 −1 1.
Otherwise, print an integer k ( 0 ≤ k ≤ 3 ⋅ n ) k(0≤k≤3⋅n) k(0k3n) — the number of operations. Then print k k k integers p 1 , p 2 , … , p k ( 1 ≤ p j ≤ n − 1 ) p_1,p_2,…,p_k (1≤p_j≤n−1) p1,p2,,pk(1pjn1), where p j p_j pj is the position of the left block in the pair of blocks that should be affected by the j j j-th operation.
If there are multiple answers, print any of them.

题意

给定一串黑白文本,每次可以将其中相邻2个颜色翻转,求一个可行的操作序列使得操作后颜色相同。
如果不能找到输出-1

思路

一开始看到 n < = 200 n<=200 n<=200直接打了一发爆搜+记忆化,然后MLE炸到飞起……
正解是假定操作后全白,从头扫到尾一次,假定全黑,从头扫到尾一次,看看能否成功。
比如:我们要全白,而此时颜色是 黑白黑黑黑
可以将黑视作高台阶,白视作低台阶,然后一路推过去,最后能推平就可以了。
例子
推平位置1后,往后找到位置2,推平位置2后,2 3都平了,再往后遍历找到位置4,推平位置4后,全部推平,合法。
因此操作序列就为:1 2 4
显然这样操作只会有2种结果:全平或者最后一个不平。
全黑全白两个都扫一遍就好了,复杂度 O ( n ) O(n) O(n)

Code

#include <cstdio>
#include <cstring>
using namespace std;
int n,len;
char all[201];
char temp[201];
int path[201];
int tot;
bool checkblack()
{
    memcpy(temp,all,sizeof(all));
    tot = 0;
    for(int i = 1;i<len;++i)
    {
        if(temp[i] == 'W')
        {
            temp[i] = 'B';
            temp[i+1] = (temp[i+1] == 'W' ? 'B' : 'W');
            path[++tot] = i;
        }
    }
    return temp[len] == 'B';
}
bool checkwhite()
{
    memcpy(temp,all,sizeof(all));
    tot = 0;
    for(int i = 1;i<len;++i)
    {
        if(temp[i] == 'B')
        {
            temp[i] = 'W';
            temp[i+1] = (temp[i+1] == 'W' ? 'B' : 'W');
            path[++tot] = i;
        }
    }
    return temp[len] == 'W';
}
int main()
{
    scanf("%d",&n);
    scanf("%s",all+1);
    len = strlen(all+1);
    if(checkblack() || checkwhite())
    {
        printf("%d\n",tot);
        for(int i =1 ;i<=tot;++i)
            printf("%d ",path[i]);
    }
    else
        printf("-1");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值