思路一:
二分答案,每次check从mid+1开始,判断能否形成要求的序列。
- #include
- using namespace std;
- #define int long long
- const int N=2e5+5;
- int t,n,a[N];
- bool check(int x){
- int p=0,i=x+1,j=n;
- while(i<=j){
- if(a[i]<=a[j]){
- if(a[i]>=p) p=a[i];
- else return false;
- i++;
- }
- else{
- if(a[j]>=p) p=a[j];
- else return false;
- j--;
- }
- }
- return true;
- }
- signed main(){
- scanf("%lld",&t);
- while(t--){
- scanf("%lld",&n);
- for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
- int l=0,r=n-1;
- while(l
- int mid=l+r>>1;
- if(check(mid)) r=mid;
- else l=mid+1;
- }
- printf("%lld\n",l);
- }
- return 0;
- }
思路二:
我们可以将数据按照大小比喻成一个“山峰”,如下图。
左侧则符合题意,右侧则只有右半边的“山峰”符合题意。所以我们从右侧模拟“上山”找到第一个山峰,然后“下山”直到无法“下山”为止即为答案。


- #include
- using namespace std;
- #define int long long
- const int N=2e5+5;
- int t,n,a[N];
- signed main(){
- scanf("%lld",&t);
- while(t--){
- scanf("%lld",&n);
- for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
- int p=n;
- while(a[p-1]>=a[p]&&p>1) p--;
- while(a[p-1]<=a[p]&&p>1) p--;
- printf("%lld\n",p-1);
- }
- return 0;
- }