【打CF,学算法——三星级】CodeForces 645C Enduring Exodus (二分+贪心)

【CF简介】

提交链接:CF 645C

题面:

C. Enduring Exodus

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

In an attempt to escape the Mischievous Mess Makers‘ antics, Farmer John has abandoned his farm and is traveling to the other side of Bovinia. During the journey, he and his
k cows have decided to stay at the luxurious Grand Moo-dapest Hotel. The hotel consists of
n rooms located in a row, some of which are occupied.

Farmer John wants to book a set of k?+?1 currently unoccupied rooms for him and his cows. He wants his cows to stay as safe as possible, so he wishes to minimize the maximum distance from his room to the room of his
cow. The distance between rooms i and
j is defined as |j?-?i|. Help Farmer John protect his cows by calculating this minimum possible distance.

Input

The first line of the input contains two integers n and
k (1?≤?k?<?n?≤?100?000) — the number of rooms in the hotel and the number of cows travelling with Farmer John.

The second line contains a string of length n describing the rooms. The
i-th character of the string will be ‘0‘ if the
i-th room is free, and ‘1‘ if the
i-th room is occupied. It is guaranteed that at least
k?+?1 characters of this string are ‘0‘, so there exists at least one possible choice of
k?+?1 rooms for Farmer John and his cows to stay in.

Output

Print the minimum possible distance between Farmer John‘s room and his farthest cow.

Examples

Input

7 2
0100100

Output

2

Input

5 1
01010

Output

2

Input

3 2
000

Output

1

Note

In the first sample, Farmer John can book room 3 for himself, and rooms
1 and 4 for his cows. The distance to the farthest cow is
2. Note that it is impossible to make this distance
1, as there is no block of three consecutive unoccupied rooms.

In the second sample, Farmer John can book room 1 for himself and room
3 for his single cow. The distance between him and his cow is
2.

In the third sample, Farmer John books all three available rooms, taking the middle room for himself so that both cows are next to him. His distance from the farthest cow is
1.

--------------------------------------------------------------------------------------啦啦啦,我是分割线--------------------------------------------------------------------------------------------------------------

题意:

一个农夫带着k头牛去住店,(人一间,每牛一间)已知该旅店共有n间房,其中部分房间已有人住,房间住宿情况由01串表示,0表示空,1表示已有人住,剩余房间足够容纳(k+1)头牛/人。为了保障牛的安全,希望人住的房间离最远的牛的房间位置尽量小,输出最小距离。

思路:

很明显为了让人住的离最远的牛最近,那么最后这批人牛住的房间肯定是连续的(不算原有的住宿人员),且人住的位置离中心点越近越好。首先,枚举住宿的左区间,如果左端点已有人住,则跳过该点,如果空,则二分以该点为左端点,空闲房间数为k+1的最左位置。随后在这个区间内,开始寻找空闲的最中心位置(距离远的那端尽量小),利用区间长度奇偶性设置两个指针p1,p2的初始位置,随后分别往两端移动,因为一定有空闲位置,且两指针同时移动,不会出现越界情况。最后找到一个解,则计算最远距离,若小于最优值,则更新。

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
char s[100010];
int room[100010];
int main()
{
    int n,k,len,le,ri,border,ans,pos;
	//读入
	scanf("%d%d",&n,&k);
	scanf("%s",s);
	room[0]=0;
	for(int i=1;i<=n;i++)
	{
		//前缀和
		if(s[i-1]-'0')
			room[i]=room[i-1];
		else
			room[i]=room[i-1]+1;
	}
	//设置一个肯定会被更新的最大值
	ans=10e6;
	for(int i=1;i<=n;i++)
	{
		//该点已有人住
	   if(room[i]==room[i-1])
		   continue;
       le=i;
	   ri=n;
	   border=-1;
	   //二分右区间
	   while(le<=ri)
	   {
		   int mid=(le+ri)>>1;
		   if(room[mid]-room[i-1]>k)
		   {

			   border=mid;
			   ri=mid-1;
		   }
		   else
			   le=mid+1;
	   }
	   //如果能找到k+1个房间
	   if(border!=-1)
	   {
         int len=(border-i),p1,p2;
		 //根据区间长度奇偶性,设置p1,p2
         if(len%2)
		 {
			 p1=(border+i)>>1;
			 p2=(border+i)/2+1;
		 }
		 else
		 {
			 p1=p2=(border+i)>>1;
		 }
		 //寻找最先出现空闲房间
		 while(1)
		 {
			 if((room[p1]!=room[p1-1]))
		    {
				pos=p1;
				break;
			}
			 else if(room[p2]!=room[p2-1])
			 {
				 pos=p2;
				 break;
			}
			 p1--;
			 p2++;
		 }
         //更新最优值
		 ans=min(ans,max(pos-i,border-pos));
	   }
	   //说明剩下,已无可能有k+1个房间
	   else
		   break;
	}
	printf("%d\n",ans);
	return 0;
}
时间: 2024-09-30 19:44:16

【打CF,学算法——三星级】CodeForces 645C Enduring Exodus (二分+贪心)的相关文章

CodeForces 645C Enduring Exodus

枚举,三分. 首先,这$n+1$个人一定是连续的放在一起的.可以枚举每一个起点$L$,然后就是在$[L,R]$中找到一个位置$p$,使得$p4最优,因为越往两边靠,距离就越大,在中间某位置取到最优解,所以三分一下就可以了. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include

【打CF,学算法——三星级】Codeforces 704A Thor (模拟)

[CF简介] 题目链接:CF 704A 题面: A. Thor time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Thor is getting used to the Earth. As a gift Loki gave him a smartphone. There are n applications on this ph

codeforces 343C Read Time 二分 + 贪心

http://codeforces.com/problemset/problem/343/C 题意: 有一些磁头,给出了起始的位置,给出了一些磁盘中需要访问的地点.求这些磁头移动的最小的次数. 思路: 二分找出满足要求的最小的时间,对于当前尝试的时间进行贪心判断是否可用.对于贪心,因为每一个磁头都需要读到还没有人读过的最左边的地方.如果这个都不能满足,那么这个时间是不可以的. 在这基础上,对于同样的这么多时间,尽可能的让这个磁头读到能读到的最右边,这样就可以将还没有读过的地方尽可能的往右推. 如

Codeforces 1132D - Stressful Training - [二分+贪心+优先队列]

题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有 $n$ 个学生,他们的电脑有初始电量 $a[1 \sim n]$,他们的电脑每分钟会耗电 $b[1 \sim n]$,现在有一场比赛持续 $k$ 分钟. 要你买一个充电器,使得每个学生的电脑在比赛期间的任何时候的电量都不会低于 $0$(可以等于 $0$),你要求出这个充电器每分钟充电量最少是多少. 题解: 看到这种题目,应当条件反射想到二分. 假设我们现在知道充电器每分钟的充电量是

1169: 零起点学算法76——绝对公正的裁判

1169: 零起点学算法76--绝对公正的裁判 Time Limit: 1 Sec  Memory Limit: 128 MB   64bit IO Format: %lldSubmitted: 510  Accepted: 336[Submit][Status][Web Board] Description 大家知道我们学校的OnlineJudge吗?,你知道他会告诉你什么呢? Compiling : 您提交的代码正在被编译.Running : 您的程序正在OJ上运行.Judging : OJ

1165: 零起点学算法72——首字母变大写

1165: 零起点学算法72--首字母变大写 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 705  Accepted: 439[Submit][Status][Web Board] Description 输入一个英文句子,将每个单词的第一个字母改成大写字母. Input 输入数据包含多个测试实例,每个测试实例是一个长度不超过100的英文句子,占一行. Output 请输出按照要求改写后的英文句

1127: 零起点学算法34——继续求多项式

1127: 零起点学算法34--继续求多项式 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 3481  Accepted: 1985[Submit][Status][Web Board] Description 输入1个正整数n, 计算1+(1+2)+(1+2+3)+...+(1+2+3+...+n) Input 输入正整数n(多组数据) Output 输出1+(1+2)+(1+2+3)+...+

1128: 零起点学算法35——再求多项式(含浮点)

1128: 零起点学算法35--再求多项式(含浮点) Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 2141  Accepted: 1002[Submit][Status][Web Board] Description 输入一个整数n,计算 1+1/(1-3)+1/(1-3+5)+...+1/(1-3+5-...+2n-1)的值 Input 输入一个整数n(多组数据) Output 出1+1/(1

1097:零起点学算法04——再模仿一个算术题

1097: 零起点学算法04--再模仿一个算术题 Time Limit: 1 Sec  Memory Limit: 128 MB   64bit IO Format: %lldSubmitted: 2627  Accepted: 2202[Submit][Status][Web Board] Description 上题会模仿了吧.再来模仿一个. 现在要求你模仿一个乘法的算术题 Input 没有输入 Output 输出9乘以10的值 Sample Output 90 Source 零起点学算法