数据结构 uva 101 - The Blocks Problem

 

题目链接:

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;
}



 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值