cf連結
洛谷連結
方法一
最大最小值問題我們很容易想到二分答案法。那麼我們如何寫出check函式呢?
對於答案x,若x-i+1<a[i],則選定怪物一定不在 i 位置左側,即L=i;
若x-n+i<a[i],則選定怪物一定不在 i 位置右側,R=min(R,i)。
遍歷陣列,如果L<=R則答案符合題意;否則不符合。
code
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e5+5; int a[N],n; int check(int x) { int l=0,r=n; for(int i=1;i<=n;i++) { if(x-a[i]+1<i) l=i; if(x-a[i]<n-i) r=min(r,i); } if(l<=r) return 1; return 0; } int main() { int maxx=-1; cin>>n; for(int i=1;i<=n;i++) cin>>a[i],maxx=max(maxx,a[i]); int l=maxx-1,r=2e9,mid; while(l+1<r) { mid=l+(r-l>>1); if(check(mid)) r=mid; else l=mid; } cout<<r; return 0; }
方法二
洛谷討論區題解。
code
#include<bits/stdc++.h> using namespace std; const int N=3e5+5; int a[N],b[N],c[N]; int MAX(int a,int b,int c){ a=max(a,b); a=max(a,c); return a; } int main(){ int n; cin>>n; for (int i=1;i<=n;i++){ cin>>a[i]; b[i]=max(b[i-1],a[i]+n-i); } for (int i=n;i>=1;i--){ c[i]=max(c[i+1],a[i]+i-1); } int ans=2e9; for (int i=1;i<=n;i++){ ans=min(ans,MAX(a[i],b[i-1],c[i+1])); } cout<<ans; return 0; }