CF1092(div3):Great Vova Wall (棧)(還不錯)
阿新 • • 發佈:2018-12-19
D1. Great Vova Wall (Version 1):
題意:給定長度為N的牆,以及每個位置的一些高度,現在讓你用1*2的磚和2*1的磚去鋪,問最後能否鋪到高度一樣。
思路:分析其奇偶性,在一個位置加1*2的磚,其奇偶性不變。在相鄰的而且高度相同的位置加2*1的磚,兩個奇偶行都改變。那麼我們不需要儲存高度,因為高度我們可以加1*2的磚,使他們等效到奇偶性的高度;所以只需要儲存奇偶,然後加入棧中,如果棧頂的兩個元素相同,則可以消去,最後如果棧元素<=1,則ok。
(如果最後棧為空,說明最後高度可奇可以偶;否則,最後的高度由棧裡剩下的一個元素奇偶性決定。
#include<bits/stdc++.h> #defineView Coderep(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; }
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