gym101522F. Frustrating Game(模拟)

                                                F. Frustrating Game

time limit per test

1.0 s

memory limit per test

256 MB

input

standard input

output

standard output

The magician Alice is playing a game. Alice has N balls in a row, consists of red balls and blue balls. For convenience, the balls are numbered 1 to N from left to right. Her goal is to transform all balls into White by casting magic spells.

In a single spell, Alice can choose exactly R red balls and B blue balls at the same time, and then cast a spell on them, so all these R + Bchosen balls will become white balls. However, there is a restriction: As some magical power may remains in the white balls, Alice cannot perform spells when there exists at least one white ball located between the leftmost chosen ball and the rightmost chosen ball.

For instance, if Alice balls 2, 6 and 7 have became white balls by previous spells, she cannot choose the set of balls {3, 8, 9} in a single spell as there exist a white ball numbered 5 between them. Similarly, single spell on balls {1, 3, 4}, {3, 4, 9} or {1, 9, 10} are invalid, while single spell on balls {3, 4, 5} or {8, 9, 10} are valid.

As Alice has spent more than hundred of years to achieve the goal and end up in failures, she is very frustrated. So, she promised that she will teach her magic skills to the one who can solve this frustrating game.

Nothing is more appealing than having an opportunity to learn magic! So you are trying to help Alice to achieve the goal.

Input

The first line contains 3 positive integers, NR and B. (R, B ≥ 1, 1 ≤ R + B ≤ N ≤ 105)

The second line contains a string S, consisting of N characters R (red) and B (blue). The i-th character is the color of the i-th ball from the left.

Output

If it is impossible to achieve the goal, output NO on the first line.

Otherwise, output YES, followed by an integer S on the second line – the number of spells (S) you would like to cast.

In the next S lines, each should indicate a spell with R + B integers, representing the indices of the balls you have selected for this spell. You can output the indices in arbitrary order within the same line.

Please note that the spells should be printed in their chronological order. If there are more than one solution, you can output any of them.

Examples

input

Copy

6 1 1
BBRBRR

output

Copy

YES
3
1 6
2 5
3 4

input

Copy

8 1 2
RBRBRBRB

output

Copy

NO

input

Copy

10 2 3
BRRRBBBRBB

output

Copy

YES
2
1 2 3 9 10
4 5 6 7 8

Note

In the first sample, the initial state is as follow:

After casting the first spell:

And after the second spell:

And the final state:

In the second sample, the initial state is as follow:

In the third sample, the initial state is as follow:

After casting the first spell:

And at last:

 

一、原题地址

点我传送

 

二、大致题意

给出n个球,每次施展魔法必须把R个红球变成白色,且必须把B个蓝球变成白色,每轮选择的这些球,最左边的一个和最右边的一个中间不能包含白球。这里题目里面的描述很迷,完全靠看Note猜想题意。

询问能否完成所有球变白,然后输出每轮的操作。

 

三、大致思路

一开始想到的是贪心的假算法,交上去WA7了,后来发现实际上这样会漏掉很多情况。

看了后台大佬的代码,真的好简单。令st为我们要取走的一段的段首,令ed为要取走的一段的段尾。那只需要模拟这一段上面有多少蓝球和红球,然后取走,再令st和ed找到对应位置,再取再复原再取....直到结束。但是输出时只要反向的输出这些操作,这样就能够保证是从两边往内部取球,而不是需要我们自己去维护顺序。至于为什么反向输出,可以自己手画一画情况,结合代码很容易理解。

自己一点一点修改代码,错了就再修改...最后几乎和大佬的改成一模一样了2333。如果侵犯到了你,请一定联系我删除!

 

四、代码

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<stack>
#include<bitset>
using namespace std;
#define PI 3.14159265
const int inf=0x3f3f3f3f;
typedef long long LL;
typedef unsigned long long ull;



int n,R,B,tot;
char s[100005];
int pre[100005],nex[100005];
int rcnt,bcnt;
int st,ed;
vector<int>ans[100005];


bool goBack()
{
    for(int i=1;i<=R+B;i++)
    {
        st=pre[st];
        if(st==0)break;
    }
    rcnt=bcnt=0;
    st=nex[st];
    ed=pre[st];
    for(int i=1;i<=R+B;i++)
    {
        ed=nex[ed];
        if(ed>n)return false;
        if(s[ed]=='R')rcnt++;
        else bcnt++;
    }
    return true;
}

bool moveTo()
{
    if(s[st]=='R')rcnt--;
    else bcnt--;
    st=nex[st];
    ed=nex[ed];
    if(ed>n)return false;
    if(s[ed]=='R')rcnt++;
    else bcnt++;
    return true;
}

void del()
{
    int t=st;
    tot++;
    for(int i=1;i<=R+B;i++)
    {
        ans[tot].push_back(t);
        t=nex[t];
    }
    st=pre[st];
    ed=nex[ed];
    nex[st]=ed;
    pre[ed]=st;
}

int main()
{
    scanf("%d %d %d",&n,&R,&B);
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
    {
        pre[i]=i-1;
        nex[i]=i+1;
    }
    nex[0]=1;
    pre[n+1]=n;
    while(true)
    {
        if(!goBack())break;
        bool ok=true;
        while(rcnt!=R||bcnt!=B)
        {
            if(!moveTo())
            {
                ok=false;
                break;
            }
        }
        if(!ok)break;
        del();
    }
    
    if(nex[0]==n+1)
    {
        printf("YES\n");
        printf("%d\n",tot);
        for(int i=tot;i>=1;i--)
        {
            for(int j=0;j<ans[i].size();j++)
            {
                if(j)printf(" ");
                printf("%d",ans[i][j]);
            }
            printf("\n");
        }
    }
    else printf("NO\n");
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值