Interesting Subarray-cf

      题意:给定一个长度为n的序列,求一个连续的子序列使得该子序列的最大元素-最小元素>=该子序列的长度(称为好序列),找不到输出NO,找到就输出YES和序列的下标l和r。

      思路:结论就是如果一个序列满足条件,则必定有两相邻元素差的绝对值>=2。故遍历一下,若每两个元素都不满足就一定不满足。

      证明:若有一个子序列满足条件,设amax为最大元素,amin为最小元素,并设max>min,则对于一个序列:amin * * * *  amax若它满足条件,则amax-amin>=max-min+1,对这个不等式进行变形-> 

(amax-amax-1)+(amax-1-amax-2)+……(amin+1-amin)>=max-min+1

而对于中间的值来说,他们取值范围是在amax和amin中间的而且是正数,若想让不等式不成立,则看首位两个括号,(amax-amax-1)和(amin+1-amin)他们必须==1,不然两个就组成好序列了,例如元素1 2 3 4 5 6,让他们排成坏序列,则首位必须是 1 2 和 5 6,那对于中间值来说,也一定要递增地排,得到 1 2 3 4 5 6是坏序列。则可得每相邻两个数的差值<=1方可是坏序列,反过来说结论成立了。

AC代码:

#include<iostream>
#include<math.h>
using namespace std;
int t,n;
int a[1000000];
int main()
{
    cin>>t;
    while(t--){
        cin>>n;
        int flag=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        for(int i=1;i<n;i++){
            if(abs(a[i]-a[i+1])>=2){
                cout<<"YES\n";
                cout<<i<<" "<<i+1<<'\n';
                flag=1;
                break;
            }
        }
        if(flag==0) cout<<"NO\n";
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/qq2210446939/p/12121736.html