1. 程式人生 > >CF1092(div3):Great Vova Wall (棧)(還不錯)

CF1092(div3):Great Vova Wall (棧)(還不錯)

D1. Great Vova Wall (Version 1):

題意:給定長度為N的牆,以及每個位置的一些高度,現在讓你用1*2的磚和2*1的磚去鋪,問最後能否鋪到高度一樣。

思路:分析其奇偶性,在一個位置加1*2的磚,其奇偶性不變。在相鄰的而且高度相同的位置加2*1的磚,兩個奇偶行都改變。那麼我們不需要儲存高度,因為高度我們可以加1*2的磚,使他們等效到奇偶性的高度;所以只需要儲存奇偶,然後加入棧中,如果棧頂的兩個元素相同,則可以消去,最後如果棧元素<=1,則ok。

(如果最後棧為空,說明最後高度可奇可以偶;否則,最後的高度由棧裡剩下的一個元素奇偶性決定。

#include<bits/stdc++.h>
#define
rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=2000010; int a[maxn],q[maxn],top; bool get(int N) { top=0; for(int i=1;i<=N;i++){ q[++top]=a[i]; if(top>=2&&q[top]==q[top-1]) top-=2; } if(top<=1) return true; return false
; } int main() { int N; scanf("%d",&N); rep(i,1,N) scanf("%d",&a[i]),a[i]=a[i]&1; if(get(N)) return puts("YES"),0; puts("NO"); return 0; }
View Code

 

D2. Great Vova Wall (Version 2)

題意:和上面一樣,只是現在只能鋪2*1的磚。

思路:開始想簡單了,以為是貪心即可,比如1,3,2,貪心出來可以鋪,錯的。事後想還是應該用棧去做。

還是用消去的思想去想,如果連續的兩個相同,我們就可以消去;如果我在中間消去了一段,那麼這一段的兩邊可以拼接起來,那麼如果這兩邊的相同,我們是否也可以消去了呢?不一定,比如1,2,2,1;我們消去了(2,2),不可以消去(1,1);原因是被中間的更高的阻斷了,我們所以維護棧的時候記錄以下中間的消去的值,如果比棧頂的大,則棧頂暫時不能消去。

(而D1不需要考慮這個問題,是因為D1的高度沒什麼約束性,只考慮奇偶。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2000010;
int a[maxn],Mx,q[maxn],h[maxn],top;
int main()
{
    int N; scanf("%lld",&N);
    rep(i,1,N) scanf("%d",&a[i]),Mx=max(Mx,a[i]);
    rep(i,1,N) {
        q[++top]=a[i];
        if(top>1&&q[top]==q[top-1]){
            if(q[top]<h[top-1]) continue;
            top-=2,h[top]=q[top+1];
            h[top+1]=0; h[top+2]=0;
        }
    }
    if(top==0||(top==1&&q[top]==Mx)) puts("YES");
    else puts("NO");
    return 0;
}
View Code