题目链接:
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;
}