题意:给定一个长度为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 "; cout<<i<<" "<<i+1<<' '; flag=1; break; } } if(flag==0) cout<<"NO "; } return 0; }