多重思想的巧妙结合
不多说了,看代码就懂了
#include<bits/stdc++.h>
using namespace std;
int up[200006]={0},down[200006]={0};
int a[200006]={0};
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=n+1;i<=2*n;i++)a[i]=a[i-n];//拆”环“成链,真的太巧妙了,隐含着环的感觉
up[1]=down[1]=1;
for(int i=2;i<=2*n;i++)
{
up[i]=a[i]>=a[i-1]?up[i-1]+1:1;//代表该点在该点所在的最长非单调递减序列中排第几
down[i]=a[i]<=a[i-1]?down[i-1]+1:1;//同理,不过是最长非单调递增序列
}
int ans=2e9;
for(int i=n;i<=2*n-1;i++)//如果存在,那么序列的末尾一定大于等于n
{
int lr=(2*n-i)%n;//left right,意思是右边剩下的数量。特殊点在于当i==n时为零
if(up[i]==n)ans=min(ans,min(lr,1+n-lr+1));//对于递增序列,要么把右边的数全部往前移,要么反转一下把包括自己在内的左边的数全部往前移(翻转过来之后就成了右边的数)
if(down[i]==n)ans=min(ans,min(lr+1,1+n-lr));//同理,这里千万要仔细,最好写的时候嘴里念叨念叨
}
printf("%d\n",ans==2e9?-1:ans);
//for(int i=1;i<=2*n;i++)printf("%d ",a[i]);//debug
//puts("");
//for(int i=1;i<=2*n;i++)printf("%d %d\n",up[i],down[i]);
}
return 0;
}
标签:Reverse,200006,int,Shift,cin,down
From: https://www.cnblogs.com/pure4knowledge/p/17889052.html