题目大意
一种新型疾病, C O W V I D − 19 COWVID-19 COWVID−19,开始在全世界蔓延。
为了控制疫情,人们被要求一定要保持社交距离,避免被感染。
现在有一个餐厅, 将
n
n
n个座位摆成一条直线,每个座位只允许一人就餐,有些位置可能已经有人就餐。
现在你和一位同学过来此餐厅吃饭,你们只能选择空位就餐,你们俩也深知社交距离的重要性,因此你们会让自己的社交距离 d d d 越远越好。
比如:
3 号位和 5 号位有人就餐,那么他们的社交距离
d
=
2
d=2
d=2。
现在你和你的同学要选择好座位后,请计算出这个餐厅最大的社交距离 。
输入格式
输入的第一行包含一个数
n
n
n, 表示座位数。
下一行包含一个长为
n
n
n 的字符串,由 0 和 1 组成,描述每个座位的状态。
0 表示空位,1 表示有人。
输出格式
一个数,表示在加入两人就餐后,可以达到的最大
d
d
d 值(最近的有人就餐间的距离)。
输入样例
14
10001001000010
输出样例
2
//样例解释
在这个例子中,可以变为 10x010010x0010,其中 x 表示两人选择的座位。此时 d=2。
基本思路
这题目乍一看是二分,但说实话没必要,就分两种情况:
- 两个人都在同一空闲区间
- 两个人安排在两个空闲区间
这样就十分简单了,我们只需要便利一遍就行了。
但是我们有许多细节要处理:
- 开头和结尾
- 全0的情况
- 原始状态下的社交距离,看题目,最大
d
d
d值并不代表就是两个人的
d
d
d值,看这种情况:
1x01101x010
此时的 d d d值是1,你看那两个挨着的1。
核心代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,a[N],cs,ans,minn=0x3f3f3f3f,tmp1,tmp2;
bool k;
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
char c;
cin>>c;
if(c=='1'){
a[++cs]=i;
k=true;
}
}
if(k==false){
cout<<n-1;
return 0;
}
for(int i=2;i<=cs;i++) minn=min(minn,a[i]-a[i-1]);
//1.两个人都在同一空闲区间
ans=max((a[1]-1)/2,(n-a[cs])/2);
//一个最前面/最后面,一个中间
for(int i=2;i<=cs;i++) ans=max(ans,(a[i]-a[i-1])/3);
//2.两个人安排在两个空闲区间
tmp1=a[1]-1;tmp2=n-a[cs];//放在最前面/最后面
//最大值与次大值
if(tmp2>tmp1) swap(tmp1,tmp2);
for(int i=2;i<=cs;i++){
if((a[i]-a[i-1])/2>tmp1){
tmp2=tmp1;
tmp1=(a[i]-a[i-1])/2;
}
else if((a[i]-a[i-1])/2>tmp2) tmp2=(a[i]-a[i-1])/2;
}
cout<<min(minn,max(ans,tmp2));
return 0;
}