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
原文地址:https://www.cnblogs.com/hua-dong/p/10142517.html