工作日(日常小题-贪心)

(时间限制: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
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;
}

你可能感兴趣的:(贪心)