思维题+栈的应用——cf1092D有意思

第一例很简单,把两个差为偶数的列不断合并即可

这种不需要撤销的合并相连数直接用栈来做

/*
如果相邻两列高度差为偶数
那么可以直接消去 
*/
#include<bits/stdc++.h>
#include<stack>
using namespace std;
#define maxn 200005
stack<int>stk;
int n,a[maxn];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
        if(stk.empty()){
            stk.push(a[i]);
        }
        else {
            if(abs(stk.top()-a[i])%2==0){
                stk.pop();
            }
            else stk.push(a[i]);
        }
    }
    if(stk.size()<2)puts("YES");
    else puts("NO");
}

第二例:只能横填

那么只要从最低的开始往上填,即不断将偶数个低列和其周围的列合并

用单调栈完美解决!

#include<bits/stdc++.h>
#include<stack>
using namespace std;
#define maxn 400005
int n,a[maxn],top;
struct Node{
    int h,w;
}stk[maxn];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
        if(top==0){
            stk[++top].h=a[i];
            stk[top].w=1;
        }
        else{
            if(stk[top].h==a[i])
                stk[top].w++;
            else if(stk[top].h<a[i]){
                while(top && stk[top].h<a[i]){
                    if(stk[top].w%2==0){
                        stk[top-1].w+=stk[top].w;
                        top--;
                    }
                    else {
                        puts("NO");
                        return 0;
                    }
                }
                if(stk[top].h==a[i])
                    stk[top].w++;
                else {
                    stk[++top].h=a[i];
                    stk[top].w=1;
                }
            }
            else if(stk[top].h>a[i]){
                stk[++top].h=a[i];
                stk[top].w=1;
            }
        }
    }
    if(top!=1){
        for(int i=2;i<=top;i++)
            if(stk[i].w%2){
                puts("NO");
                return 0;
            }
    
    }
    puts("YES");
}
原文地址:https://www.cnblogs.com/zsben991126/p/10914685.html