uva 101 - The Blocks Problem

可以看成有n块板子,每块板子上面标记有0,1,……n - 1数字。如下图所示:

对这些板子有如下几个操作:

1、move a onto b:

       上述的a和b都是板子的标号。将板子a放到b上面,且将a和b板子上的所有的板子都放回他们的初始位置。

2、move a over b:

       上述的a和b都是板子的标号。将板子a放到b板子所在堆的最上面,且将板子a上的所以板子都放回他们的初始位置。

3、pile a onto b:

       上述的a和b都是板子的标号。将板子a及a上的所有板子都放到b上,且将板子b上的所有板子都放回他们的初始位置。

4、pile a over b:

       上述的a和b都是板子的标号。将板子a及a上的所有板子都放到b板子所在堆的最上面。


这里要提醒一下,进行3操作时首先应该把a该移过去的 存起来, 然后move   b,再把刚才存的加上去。因为如果先move的话会把一些板子移到a上,此时再加就错了。。


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
using namespace std;
#define N 100
int n;
int s[N][N], top[N], pos[N]; //pos是指i的当前位置

void ini() //初始化
{
    for(int i = 0; i < n; i++)
        {s[i][0] = i; pos[i] = i;top[i]=1;}
}

void move(int id, int a)  //把某堆a上边的清空
{
    //printf("top[id]=%d a=%d\n",top[id], a);
    while(s[id][top[id]-1]!=a)
    {
       // printf("haha\n");
        int tmp = s[id][top[id]-1];
        top[id]--;
        s[tmp][top[tmp]++] = tmp;
        pos[tmp] = tmp;
    }
}

void print() //输出
{
    for(int i = 0; i < n; i++)
    {
        printf("%d:",i);
        for(int j = 0; j < top[i]; j++)
            printf(" %d", s[i][j]);
        printf("\n");
    }
}

int main()
{
    while(~scanf("%d", &n))
    {
        char a1[N], a2[N];
        int a, b;
        ini();
        while(scanf("%s",a1))
        {
            if(strcmp(a1, "quit")==0)
                break;
            scanf("%d%s%d", &a, a2, &b);

            if(a==b||pos[a]==pos[b])
                continue;
            if(a1[0]=='m')
            {
                move(pos[a],a);
                top[pos[a]]--;
                pos[a] = pos[b];
                if(a2[1]=='n')
                    move(pos[b], b);
                s[pos[b]][top[pos[b]]++] = a;
            }
            else
            {
                int tmp[N],cnt=0;
                int id = pos[a];
                while(1)
                {
                    tmp[cnt++] = s[id][top[id]-1];
                    top[id]--;
                    pos[tmp[cnt-1]] = pos[b];
                    if(tmp[cnt-1]==a)
                        break;
                }
                if(a2[1]=='n')
                    move(pos[b], b);
                for(int i = cnt-1; i >= 0; i--)
                    s[pos[b]][top[pos[b]]++]=tmp[i];
            }
        }
        print();
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值