題目大意:
一個數列是尖銳的
當且僅當存在一個位置k使得 a[1]<a[2]<a[3]<...<a[k] 且 a[k]>a[k+1]>a[k+2]>...>a[n]
現在你可以任意讓某些嚴格為正整數的元素執行操作使它們的值 -1
問能不能通過這么一系列操作去銳化這個數組(也可以不操作)
注意,嚴格遞增或者嚴格遞減的數組也是尖銳的(k可以為1或者n)
解題思路:
要銳化一個數組
只需要讓他能夠滿足完全遞增、完全遞減、先遞增后遞減即可
因為任意元素都能執行任意次-1
所以不妨直接化成最直觀的答案
即最后化成類似 0 1 2 3 ... 3 2 1 0 的樣式
如果數組元素個數為奇數,如上可滿足
但是如果為偶數,中間兩位不能相同
根據上方的最簡樣式,可以得到,從前往后一直到k位置,數組是遞增的
從后往前看到第k個位置,數組還是遞增的
所以不妨去循環判斷每一個元素是否滿足條件
即從前往后,i=0~n-1,判斷每一位是否滿足ar[i]>=i
如果不滿足,說明從前往后的遞增斷在了這個位置
用變量pl記錄這個位置
從后往前,i=n-1~0,判斷每一位是否滿足ar[i]>=n-i+1
如果不滿足,說明從后往前遞增斷在了這個位置
用變量pr記錄這個位置
(注意完全遞增遞減的情況下對pl和pr的特殊處理)
最后,判斷pl>=pr是否成立,成立則說明數組可以銳化,否則,pl到pr之間這一段無法進行銳化
#include<bits/stdc++.h> using namespace std; int ar[300050]; void solve(){ int N,i,tmp,pl,pr; bool flag=true; cin>>N; if(N==1) cin>>ar[1]; else if(N==2){ cin>>ar[1]>>ar[2]; if(ar[1]+ar[2]==0) flag=false; } else if(N>=3){ for(i=0;i<N;i++) cin>>ar[i]; for(i=0;i<N;i++) if(ar[i]<i){ pl=i-1; break; } if(i==N) pl=N-1; for(i=N-1;i>=0;i--) if(ar[i]<N-i-1){ pr=i+1; break; } if(i==-1) pr=0; if(pl<pr) flag=false; } cout<<(flag?"Yes\n":"No\n"); } int main(){ ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); int T;cin>>T;while(T--) solve(); return 0; }