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, N, R 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;
}