社交距离 I(分类讨论)
题意:给你长度为n的字符串,其中0表示此位置没有牛,1表示此位置有牛。让你在不移动其他牛的情况下,插入两头牛,求最近两头牛位置位置差的最大值。
思路:先用p[i]记录第i头牛的位置。设xmin为未插入牛的情况下最近距离。可以分成两种情况讨论。①两头牛插在同一区间。②两头牛插在不同的区间。第一种情况:若第一段区间为000001,则一定是在位置1插入,再在中间插入另一头牛,即x00x01是最优的,产生的最近距离为y=(p[1]-1)/2 (向下取整)。同理最后一段,最近距离为y=(n-p[cnt])/2。对于两端有牛的区间i,产生的最近距离为y=(p[i+1]-p[i])/3 (向下取整),每段区间的y不断取max。则第一种情况的答案为min(y,xmin).第二种情况:首端的情况p[1]-1,尾段的情况为n-p[cnt],枚举中间位置,更新最大值y1和次大值y2。第二种的答案为min(xmin,y2),最终答案是两种答案取最大
#include <bits/stdc++.h> #define lowbit(x) x&(-x) #define endl #define sf(x) scanf("%d",&x) #define rep(i,x) for(i=0;i<(x);i++) #define gen(x) x##_ #define ios std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0) #define PII pair<int,int> typedef long long ll; const int N=1e5+10; const int inf=0x3f3f3f3f; using namespace std; char str[N]; int p[N]; int n,cnt; void solve() { scanf("%d%s",&n,str+1); for(int i=1;i<=n;i++) { if(str[i]==1) p[++cnt]=i; } if(!cnt) cout<<n-1<< ;//初始为空的情况 else { //第一种情况,两头牛在同一区间 int xmin=inf; for(int i=1;i<cnt;i++) { xmin=min(xmin,p[i+1]-p[i]); } int y=max((p[1]-1)/2,(n-p[cnt])/2);//首 尾 for(int i=1;i<cnt;i++)//枚举中间位置 { y=max(y,(p[i+1]-p[i])/3); } //第二种情况,两头牛在不同区间 int y1=p[1]-1,y2=n-p[cnt]; if(y2>y1) 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(d>y2) y2=d; } cout<<min(xmin,max(y2,y)); } } int main() { //ios; int _t=1; //cin>>_t; while(_t--) { solve(); } system("pause"); return 0; }