(时间限制:1秒 内存限制:128MB)
【题目描述】
Tom决定从明天开始,在给定的N天里面,选择K天出来工作。
给定一个整数C和一个字符串S(每天对应一个字符),Tom的工作日选择如下:
(1)工作一天后,他将不再在随后的C天工作。
(2)如果S的第i个字符是x,则他不会在第i天工作。其中的第1天就是明天,第
2天是后天,依此类推。
请你编程找出Tom必须要工作的所有日子。
如果没有必须工作的日子,则什么都不输出。
【数据范围】
1≤N≤2×10
5
;1≤K≤N;0≤C≤N;
N是S的长度;S包含的字符只有o或x ;
【输入格式】
输入一行为三个正整数,即N,K和C,相邻两个整数之间均用一个空格隔开的。
第二行是字符串S。
【输出格式】
按升序打印Tom将要工作的所有天的编号,每行一天。
如果没有必须工作的日子,则什么都不输出(样例3)。
【输入样例1】
11 3 2
ooxxxoxxxoo
【输出样例1】
6
【样例1说明】
Tom将在11天中选择3天出来工作,工作一天后,他将在随后的两天内停止工作。
由于他的工作日有如下四种可能的选择:
第1种选择:第1天、第6天、第10天;
第2种选择:第1天、第6天、第11天;
第3种选择:第2天、第6天、第10天
第4种选择:第2天、第6天、第11天。
所以,他必须在第6天工作,答案为6.
【输入样例2】
5 2 3
Ooxoo
【输出样例2】
1
5
思路
求必须工作的日子,只需正反各扫描一次,记录工作日,求工作日交集即可。
代码
#include<bits/stdc++.h>
using namespace std;
int n,c,k;
int l[200010],r[201000];
char s[201000];
int main()
{
//freopen("work.in","r",stdin);
//freopen("work.out","w",stdout);
scanf("%d%d%d",&n,&k,&c);
scanf("%s",s);
int cnt=k-1,mx=n;
for(int i=strlen(s)-1;i>=0;i--)
if(cnt>=0&&i<mx&&s[i]=='o')
{
r[cnt]=i;
mx=i-c;
cnt--;
}
cnt=0,mx=-1;
for(int i=0;i<strlen(s);i++)
if(i>mx&&s[i]=='o')
{
l[cnt]=i;
mx=i+c;
cnt++;
}
for(int i=0;i<k;i++)
if(l[i]==r[i])cout<<l[i]+1<<endl;
return 0;
}