CF1092 D Great Vova Wall —— 思路+單調棧
阿新 • • 發佈:2018-12-21
題目:https://codeforces.com/contest/1092/problem/D1
https://codeforces.com/contest/1092/problem/D2
很有趣的題;
對於D1,首先發現兩種磚的放法和高度的奇偶性有關(!);
而豎著放的磚不改變一列的奇偶性,也就是確定一列的奇偶性後,它的高度是可以任意的,那麼我們就不用考慮實際高度的問題了;
然後發現,如果兩列奇偶性相同的列相鄰了,那麼它們就“無敵”了,可以變成任意高度;
而兩列可以合併,只能是它們相鄰且奇偶性相同;
這就很像兩組括號序列啊!奇數是 (),偶數是 [],那麼整個序列就是 (, ), [, ] 相間的;
只要棧頂能完成一個匹配,就彈棧表示這兩列“無敵”了;
所以最後要是棧裡沒有元素或只剩下一個元素,序列就是合法的,否則不合法;
這麼簡單就做完了!
程式碼如下:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int const xn=2e5+5; int n,sta[xn],top; int rd() { int ret=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}D1while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return f?ret:-ret; } int main() { n=rd(); for(int i=1,x;i<=n;i++) { x=rd(); if(top&&(x&1)==(sta[top]&1))top--; else sta[++top]=x; } if(top<=1)puts("YES"); else puts("NO"); return0; }
對於D2,只能放橫著的磚;
那就更簡單了,每次先填滿最低的一段,如果其長度是奇數就不合法了,否則就和旁邊的合併成一段;
這個過程可以用單調棧維護。
程式碼如下:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int const xn=2e5+5; int n,sta[xn],top,len[xn],a[xn]; int rd() { int ret=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();} while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return f?ret:-ret; } int main() { n=rd(); for(int i=1;i<=n;i++)a[i]=rd(); for(int i=1,l,j;i<=n;i=j+1) { j=i; l=0; while(a[i]==a[j+1])j++; while(top&&a[i]>sta[top]) { if(len[top]&1){puts("NO"); return 0;} l=len[top]; top--; if(top&&sta[top]<a[i])len[top]+=l; else break; } while(top&&sta[top]==a[i])l+=len[top--]; sta[++top]=a[i]; len[top]=l+(j-i+1); //printf("sta[%d]=%d len=%d\n",top,sta[top],len[top]); } int l=0; while(top>1) { l+=len[top--]; if(l&1){puts("NO"); return 0;} } puts("YES"); return 0; }D2