UVA - 101 The Blocks Problem

题目链接 https://vjudge.net/problem/UVA-101#author=0

背景

在计算机科学中的很多地方都会使用简单,抽象的方法来做分析和实验验究。比如在早期的规划学和机器人学的人工智能研究就利用一个积木世界,让机械臂执行操作积木的任务。
在这个问题中,你将在确定的规则和约束条件下构建一个简单的积木世界。这不是让你来研究怎样达到某种状态,而是编写一个“机械臂程序”来响应有限的命令集。

问题

问题就是分析一系列的命令,告诉机械臂如何操纵放在一个平台上的积木。最初平台上有n个积木(编号由0到n - 1),对于任意的0 ≤ i < n - 1,积木bi都与bi + 1相临,图示如下:

机械臂操作积木的有效指令列举如下:
*move a onto b
a和b都是积木的编号,先将a和b上面所有的积木都放回原处,再将a放在b上。
*move a over b
a和b都是积木的编号,先将a上面所有的积木放回原处,再将a放在b上。(b上原有积木不动)
*pile a onto b
a和b都是积木的编号,将a和其上面所有的积极组成的一摞整体移动到b上。在移动前要先将b上面所有的积极都放回原处。移动的一摞积木要保持原来的顺序不变。
*pile a over b
a和b都是积木的编号,将a和其上面所有的积极组成的一摞整体移动到b所在一摞积木的最上面一个积木上。移动的一摞积木要保持原来的顺序不变。
*quit
结束积木世界的操纵。
当a = b或a和b处在同一摞时,任何企图操作a和b的命令都是非法的。所有非法的命令都要忽略,且不能对当前积木的状态产生作用。

输入

输入由1个整数n开始开始,该整数独占一行,表示积木世界中的积木数量。你可以假定0 < n < 25。
从积木数量值的下一行开始是一系列的命令,每条命令独占一行。你的程序要处理所有的命令直到输入退出命令。
你可以假定所有的命令都按上文所示的格式给出。不会出现语法错误的命令。

输出

以积木世界的最终状态作为输出。每一个原始积木的位置i(0 ≤ i < n,n为积木数量)后面都要紧跟一个冒号。如果至少有一个积木在该位置上,冒号后面都要紧跟一个空格,然后是该位置上所有积木编号的序列。每2个积木的编号之间以一个空格隔开。行尾不能出现多余的空格。
每个积木位置独占一行(即第一行输入的n,对应输出n行数据)。

样例输入

10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
quit

样例输出

0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:

AC代码

#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=30;
int n;
vector<int> pile[maxn];
void find1_block(int a,int&p,int&h) //找到木块a所在的pile和height
{
    for( p=0;p<n;p++)
    for( h=0;h<pile[p].size();h++){
        if(pile[p][h]==a)
            return;}
}
void re_block(int p,int h) //把第p堆高度位h的木块上方的木块移动回原位
{
    for(int i=h+1;i<pile[p].size();i++)
    {
        int b=pile[p][i];
        pile[b].push_back(b);
    }
    pile[p].resize(h+1);
}
void move_block(int p,int h,int p2) //把第p堆高度为h及其上方的木块整体移动到p2堆得顶部
{
    for(int i=h;i<pile[p].size();i++){
        pile[p2].push_back(pile[p][i]);
    }
    pile[p].resize(h);
}
void print() //输出
{
    for(int i=0;i<n;i++){
        printf("%d:",i);
        for(int j=0;j<pile[i].size();j++)
         printf("% d",pile[i][j]);
         printf("\n");
    }
}
int main()
{
    cin>>n;
    int a,b;
    for(int i=0;i<n;i++) pile[i].push_back(i);
    string s1,s2;
    while(cin>>s1&&s1!="quit"){
        cin>>a>>s2>>b;
        int pa,pb,ha,hb;
        find1_block(a,pa,ha);
        find1_block(b,pb,hb);
        if(pa==pb) continue;
        if(s2=="onto")  re_block(pb,hb);
        if(s1=="move")  re_block(pa,ha);
        move_block(pa,ha,pb);
    }
    print();
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值