牛客寒假算法基础训练营1 G

题目链接:https://ac.nowcoder.com/acm/contest/317/G

这道题的题解讲的非常好了已经,对于1~n数的排列子区间[l,r],使得区间中的数满足连续的条件为:r-l=max(a[l~r])-min(a[l~r]);

(l,r为下标)

既然要使[l,r]为萌区间,那么就要找到这个区间内的最大值mx与最小值mn,判断是否满足条件;

若不满足条件,那么需要将[mn,mx]缺少的数字都加入区间内(什么意思呢,当前区间[l,r]内的数字不连续,我们要使区间元素变的连续起来就得使得从最小值到最大值期间的所有元素都出现,所以才有了扩充区间一说),然后计算新的区间的长度,继续迭代,直到满足条件。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const double epos=1e-8;
const int maxn=1e5+7;
int a[maxn];
int pos[maxn];


int main(){
    int l,r;
    int n;
    int x,y;
    scanf("%d%d%d",&n,&x,&y);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        if(a[i]==x) l=i;
        if(a[i]==y) r=i;
        pos[a[i]]=i;
    }
    if(l>r) swap(l,r);
    int mx=-1,mn=inf;

    while(r-l!=mx-mn){
        for(int i=l;i<=r;++i){
            mx=max(mx,a[i]);
            mn=min(mn,a[i]);
        }

        for(int i=mn;i<=mx;++i){
            l=min(l,pos[i]);
            r=max(r,pos[i]);
        }
    }
    printf("%d %d\n",l,r);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/chenyume/article/details/87925424