Codeforces 1291B - Array Sharpening


題目大意:

一個數列是尖銳的

當且僅當存在一個位置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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM