手工数据结构系列-C语言模拟栈 hdu1022

这个题我一开始是这么想的。。

爆搜所有可能的出栈序列

然后对输入进行匹配

这样我感觉太慢

然后我们可以想到直接通过入栈序列对出栈序列进行匹配

但是我犯了一个错误。。那就是出栈序列一定到入栈序列里找。。

找不到的入栈,最后弹栈,弹不空的就是不合法序列

但是这里有一个逻辑不对。。为什么最后才弹栈呢。。为什么中间不能从非空栈中弹栈呢

所以,出栈序列要么和入栈序列匹配要么和已经入栈的栈顶匹配,要么安排入栈序列元素入栈,

如果入栈序列和入栈的栈顶都无法匹配且入栈序列无法入栈,那么匹配出错

对于5 12324 24321虽然可以合法出栈。。但是这题并不care

如果有这种多个相同编号的情况,我们需要dfs一下所有入栈和出栈的情况

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//================= Stack ==================================
#define __init_size 1000
typedef struct{
    int size,__size,head,tail,*seq;
}Stack;

typedef Stack* S_P;
void __init(S_P s){
    s->head=s->tail=s->size=0;
    s->__size=__init_size;s->seq=(int*)malloc(__init_size*sizeof(Stack));//少了__init_size
}
int __empty(S_P s){
    if(s->head==s->tail) return 1;
    return 0;
}
void __push(S_P s,int ele){
    if(s->tail+1>=s->__size){
        s->seq=(int*)realloc(s->seq,sizeof(Stack)*(s->__size+=__init_size));
    }
    s->seq[s->tail++]=ele;s->size++;
}
void __pop(S_P s){
    if(!__empty(s)) s->tail--,s->size--;
}
int __top(S_P s){
    if(!__empty(s)) return s->seq[s->tail-1];
}
void __test(){
    S_P s=(S_P)malloc(sizeof(S_P));__init(s);
    int i;for(i=0;i<10;++i)  __push(s,i);
    while(!__empty(s)) {printf("%d ",__top(s));__pop(s);}
    printf("\n");
}
//=========== SOLVE FUNCTION =======================================
int a[10],b[10],c[20],d[20],cc,n,finish;
char str[11];
void solve(){
    S_P s=(S_P)malloc(sizeof(Stack));__init(s);
    int i;
    while(~scanf("%d",&n)){
        while(!__empty(s)) __pop(s);
        memset(a,-1,sizeof(a));
        memset(b,-1,sizeof(b));
        scanf("%s",str+1);
        for(i=1;i<=n;++i) a[i]=str[i]-'0';
        scanf("%s",str+1);
        for(i=1;i<=n;++i) b[i]=str[i]-'0';//命名重名问题
        int c_out=1,cc=0,flag=1;i=1;
        while(c_out<=n){
            if(a[i]==b[c_out]) {
                i++;c[cc++]=1;c[cc++]=0;c_out++;
            }
            else if(!__empty(s)&&__top(s)==b[c_out]) {__pop(s);c_out++;c[cc++]=0;}
            else if(i<=n){
                __push(s,a[i]);i++;c[cc++]=1;
            }
            else{
                flag=0;break;
            }
        }
        if(flag){
            printf("Yes.\n");
            for(i=0;i<cc;++i){
                if(c[i]==0) printf("out\n");
                else if(c[i]==1) printf("in\n");
                else     printf("in\nout\n");
            }
        }
        else{printf("No.\n");}
        printf("FINISH\n");
    }
}

int main(){
    solve();
    return 0;
}

 

转载于:https://www.cnblogs.com/linkzijun/p/6501647.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值