我也不想瞒着大家,这道题一共17个案例,这个方法只能过16个,另外一个是答案错误,但是本菜找不到bug,希望大家帮我找一下,既然过了16个案例,那么说明也有一定的可取性【为了不误人子弟,本菜才写这些】
说一下本菜的思路吧,这道题的数据说明我们要用o(nlogn)的时间复杂度的算法,所以我想到的一个就是二分,当然这道题的最优解是贪心;
下面是本菜的思路:
先用fix[N]数组预处理前缀和数组
(1):确认答案存在的区间为1~n;
(2):进入check函数,参数为mid:
1:用前缀和数组判断每一个合法的位置,即在一个点左右mid的范围内没有牛【这个可以用前缀和数组用o(1)的时间复杂度来判断;
2:如果合法,那么我们就用这个位置更新合法位置的最大值和最小值【这里用mx和mi两个变量来记录】
上面就算本菜的思路,下面是本菜的代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int fix[N],st[N];
int n;
bool check(int t){
int mi=1e9,mx=-1;
for(int i=1;i<=n;i++){
if(st[i]) continue;
int p1,p2;
if(i+t<=n) p1=i+t;
else p1=n+1;
if(i-t>=1) p2=i-t;
else p2=0;
if(fix[p1-1]-fix[i]==0&&fix[i-1]-fix[p2]==0)
mi=min(mi,i); mx=max(mx,i);
if(mx!=-1&&mi!=1e9){
if(mx-mi>=t) return 1;
}
}
return 0;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
char a; cin>>a;
if(a=='\n') continue;
st[i]=a-'0';
fix[i]=st[i]+fix[i-1];
}
int l=0,r=n;
while(l<r){
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
cout<<l;
}