zoj 1004 回溯啊,牛~~
一题就是要把一个输入串仅仅通过栈的入栈和出栈操作转化为另一个串。初看此题,我感觉非常难以下手,不知道该如何是好。 仔细分析题目中的两个串之间有什么规律,时间花了很多的,但是一点效果都没有。请教了一位ACM很牛的同学。他马上就说了一句话,直击题目的核心。就是你不用电脑,只用纸和笔,你会怎么算呢?是的,如果我只用纸和笔,我会怎么做呢?我想对于madam和adamm这两个串来说,当然就是先入m,然后在入a,然后弹出a,然后重复此过程直到找到一种出栈、入栈序列为止。他说,你把你的这个思考过程转化成代码,让电脑能够执行不就行了吗?
下面是我的代码。代码的执行过程就是边入栈,边匹配,匹配了就出栈,不匹配就继续入栈,直到找到所有的可能的入栈、出栈序列为止。为了能够找到所有可能的序列,还需要在递归搜索过程中,从递归函数返回时恢复原来的环境,以便能够继续搜索。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/archimedes_zht/archive/2008/04/19/2306036.aspx
#include<iostream> #include<string> using namespace std; #define MaxSize 100 typedef struct Stack { char list[MaxSize]; int count; }DataType; DataType Q; char *first,*second; int Count=0; char Chuan[MaxSize]; void Initiate(DataType *x) { x->count=0; } bool isEmpty(DataType x) { if(x.count<=0) return true; return false; } void Push(DataType *x,char m) { if(x->count>=MaxSize-1) { cout<<"Error"<<endl; return; } x->list[x->count]=m; x->count++; } char Pop(DataType *x) { if(x->count<=0) {cerr<<"error!"<<endl;} --x->count; return x->list[x->count]; } char Peek(DataType x) { if(x.count<=0) {cerr<<"error!"<<endl;} return x.list[x.count-1]; } void Try() { if(*second=='\0') { for(int i=0;i<Count;i++) cout<<Chuan[i]<<" "; cout<<endl; } if(*first!='\0') { Push(&Q,*first); Chuan[Count++]='i'; ++first; Try(); Pop(&Q); --Count; --first; } if(!isEmpty(Q)){ //还原!!!!! char c=Peek(Q); if(c==*second) { Pop(&Q); Chuan[Count++]='o'; ++second; Try(); Push(&Q,c); --Count; --second; } } } int main() { string x1,x2; while(cin>>x1>>x2) { first=(char*)(x1.c_str()); second=(char*)(x2.c_str()); cout<<"["<<endl; Try(); cout<<"]"<<endl; } return 0; }