AcWing 1659. 社交距离 I
原题链接
简单
作者:
不幸到吃土
,
2025-01-16 00:31:10
,
所有人可见
,
阅读 2
//分类讨论思想:(1)新加的两头牛在同一个区间 (2)新加的两头牛不在同一个区间
/*
要求两头牛之间距离最小的最大值,先将"已有牛"之间的距离求出来,设为x_min
不难发现:某头牛取中点时,该牛与左、右邻近两牛之间的距离最大
情况(1)
①若在开头区间
一头牛放最左端,一头牛放中点:dist = (p[1] - 1)/2
②若在结尾区间
一头牛放最右点,一头牛放中点:dist = (n - p[m])/2
③若在中间区间
两头牛构成当前区间的三等分点:dist = (p[i+1] - p[i])/3
情况(2)
此时分别求出新加的两头牛与邻近牛之间距离的最大值(逐个区间进行枚举)
*/
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010 , INF = 1e9;
char str[N];
int p[N]; //记录已有牛所处的位置
int main(){
int n;
cin >> n >> str+1;
int cnt = 0; //记录已有牛的数量
for(int i=1;i<=n;i++){
if(str[i] == '1')
p[++cnt] = i;
}
if(!cnt){ //若新加之前,没有一头牛
cout << n-1 << endl;
return 0;
}
int x_min = INF;
for(int i=1;i<cnt;i++){ //计算"已有牛"之间的距离
x_min = min(x_min,p[i+1]-p[i]);
}
//考虑情况(1)
int dist = max((p[1]-1)/2,(n-p[cnt])/2);
for(int i=1;i<cnt;i++){
dist = max(dist,(p[i+1]-p[i])/3);
}
//考虑情况(2)
int y1 = p[1] - 1, y2 = n-p[cnt]; //新加的两头牛:一头在最左端,另一头在最右端
if(y1 < y2)
swap(y1,y2); //令y1取得最大值,y2取得次大值
for(int i=1;i<cnt;i++){
int d = (p[i+1]-p[i])/2;
if(d >= y1){ //更新最大值及次大值
y2 = y1;
y1 = d;
}else if(y2 < d){ //更新次大值
y2 = d;
}
}
int ans = min(x_min,max(dist,y2)); //由于求最小的最大值,故比较情况(1)的dist和情况(2)的y2
cout << ans << endl;
return 0;
}