算法 木块问题 UVa 101

原文链接: https://vjudge.net/problem/UVA-101

Descriptions:

初始时从左到右有n个木块,编号为0~n-1,要求实现下列四种操作:

move a onto b: 把a和b上方的木块全部放回初始的位置,然后把a放到b上面
move a over b: 把a上方的木块全部放回初始的位置,然后把a放在b所在木块堆的最上方
pile a onto b: 把b上方的木块部放回初始的位置,然后把a和a上面所有的木块整体放到b上面
pile a over b: 把a和a上面所有的木块整体放在b所在木块堆的最上方
一组数据的结束标志为"quit",如果有非法指令(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:

题目链接:https://vjudge.net/problem/UVA-101

每个木块堆的高度不确定,所以用vector来保存很合适,而木块堆的个数不超过n,所以用一个数组来保存就可以了。代码如下

#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=30;
int n;
vector<int> pile[maxn];//每一个pile[i]都是一个vector
//找木块a所在的pile和height,以引用的形式返回调用者
void find_block(int a,int& p,int& h)
{
    for (p=0;p<n ;p++ )
        for(h=0;h<pile[p].size();h++)
            if(pile[p][h]==a) return;
}
//把第p堆高度为h的木块上方的所有木块移回原位
void clear_above(int p,int h)
{
    for(int i=h+1;i<pile[p].size();i++){
        int b=pile[p][i];
        pile[b].push_back(b);//把木块b放回原位
    }
    pile[p].resize(h+1);//pile只应保留下标0~h的元素
}
//把第p堆高度为h及上方的木块整体移动到p2堆的顶部
void pile_onto(int p,int h,int 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()
{
    int a,b;
    cin>>n;
    string s1,s2;
    for (int i=0;i<n ;i++ ) pile[i].push_back(i);
    while (cin>>s1>>a>>s2>>b)
        {
            int pa,pb,ha,hb;
            find_block(a,pa,ha);
            find_block(b,pb,hb);
            if(pa==pb) continue;
            if(s2=="onto") clear_above(pb,hb);
            if(s1=="move") clear_above(pa,ha);
            pile_onto(pa,ha,pb);
        }
        print();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43269048/article/details/99697184