题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=37
题目意思:
开始给定编号为0-n的数分别在1-n栈里,然后执行四种操作,求最后这n个栈中的数据情况
四种操作规则:
1.move a onto b
把a所在栈a上面的数据回归到初始状态,把b所在栈b上面的数据回归到初始状态,然后把a放到b上面
2.move a over b
把a所在栈a上面的数据回归到初始状态,然后把a放到b上面
3.pile a onto b
把b所在栈b上面的数据回归到初始状态,然后把a所在栈包括a元素在内的所有元素按在该栈的顺序不变,全部移到b所在的栈上
4.pile a over b
把a所在栈包括a元素在内的所有元素按在该栈的顺序不变,全部移到b所在的栈上
解题思路:
用栈来模拟执行过程,注意数据为0-n-1,回归的时候注意加一。细节详见代码
代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #define eps 1e-6 #define INF (1<<20) #define PI acos(-1.0) using namespace std; struct Stack //模拟栈 { int top; int save[100]; int pop() { return save[top--]; } int push(int n) { ++top; return save[top]=n; } bool empty() { if(top==0) return true; return false; } void clear() { top=0; } int finda(int a) { for(int i=1;i<=top;i++) //在栈中找数的位置 if(save[i]==a) return i; return 0; } }; Stack stack[100]; int n; int find(int a) //找数a属于哪一个栈 { for(int i=1;i<=n;i++) { int j=stack[i].finda(a); if(j) return i; } } void removeup(int local,int a) //将a上面的元素全部回归 { //while(stack[local].save[stack[local].top]!=a) int limit=stack[local].finda(a); for(int i=limit+1;i<=stack[local].top;i++) { int temp=stack[local].save[i]; stack[temp+1].push(temp); /* stack[temp+1].clear(); //注意回归时应与加一对应,坑死了 stack[temp+1].push(temp);*/ } stack[local].top=limit; //注意现在该栈的元素个数 return ; } void removewhole(int locala,int a,int localb) //将a所在栈包括a以及以上的所有元素全部按顺序移到b所在栈上 { int i=stack[locala].finda(a); //先找到a的位置 int temp=i; for(;i<=stack[locala].top;i++) { stack[localb].push(stack[locala].save[i]); } stack[locala].top=temp-1; //注意更新栈a的元素个数 return ; } void moveonto(int a,int b) { int tempa=find(a),tempb=find(b); if(tempa==tempb) return ; removeup(tempa,a); removeup(tempb,b); stack[tempb].push(a); //将a移向b stack[tempa].top--; return ; } void moveover(int a,int b) { int tempa=find(a),tempb=find(b); if(tempa==tempb) return ; removeup(tempa,a); stack[tempb].push(a); //将a移向b stack[tempa].top--; return ; } void pileonto(int a,int b) { int tempa=find(a),tempb=find(b); if(tempa==tempb) return ; removeup(tempb,b); removewhole(tempa,a,tempb); return ; } void pileover(int a,int b) { int tempa=find(a),tempb=find(b); if(tempa==tempb) return ; removewhole(tempa,a,tempb); } void print() { for(int i=1;i<=n;i++) { printf("%d:",i-1); if(!stack[i].empty()) { for(int j=1;j<=stack[i].top;j++) printf(" %d",stack[i].save[j]); } putchar('\n'); } return ; } int main() { int a,b; char com1[20],com2[20]; while(cin>>n) { for(int i=1;i<=n;i++) { stack[i].clear(); stack[i].push(i-1); } //print(); while(cin>>com1&&strcmp(com1,"quit")) { scanf("%d%s%d",&a,com2,&b); if(a==b) continue; if(strcmp(com1,"move")==0) { if(strcmp(com2,"onto")==0) moveonto(a,b); else moveover(a,b); } else { if(strcmp(com2,"onto")==0) pileonto(a,b); else pileover(a,b); } // print(); } print(); } return 0; }