D. Yet Another Monster Fight

黑屿白發表於2024-06-22

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;
}

相關文章