您的位置:首页 > 其它

UVa-101 The Blocks Problem

2015-08-18 13:10 302 查看
#include <iostream>
#include <string>
#include <cstdio>
#include <vector>

using namespace std;

const int maxn = 25 + 5;
vector<int> block[maxn];
string str1, str2;
int pile_a, height_a, pile_b, height_b;     //a的堆序号 a所在的高度 b的堆序号 b所在的高度
int a, b;
int n;

inline void find_block(int temp, int& pile, int& height)            //找到木块a、b所在的堆序号pile和高度height,以引用的形式返回调用者
{
for(pile = 0; pile < n; pile ++)
for(height = 0; height < (int)block[pile].size(); height ++)
if(block[pile][height] == temp)
return;
}

inline void clear_above(int pile, int height)                       //把第pile堆高度为height的木块上方所有的木块移回原位
{
for(int i = height + 1; i < (int)block[pile].size(); i ++)
{
int temp = block[pile][i];
block[temp].push_back(temp);        //把木块temp放回原位
}
block[pile].resize(height + 1);         //block只应保留下标0~height的元素
}

inline void pile_onto(int pile1, int height, int pile2)             //把第pile1堆高度为height及其上方的木块整体移动到pile2堆的顶部
{
for(int i = height; i < (int)block[pile1].size(); i ++)
block[pile2].push_back(block[pile1][i]);
block[pile1].resize(height);
}

inline void print()                         //格式输出
{
for(int i = 0; i < n; i ++)
{
printf("%d:", i);
for(int j = 0; j < (int)block[i].size(); j ++)
printf(" %d", block[i][j]);
printf("\n");
}
}

int main()
{
cin >> n;
for(int i = 0; i < n; i ++)
block[i].push_back(i);              //初始vector
while(cin >> str1)
{
if(str1 == "quit")
break;
cin >> a >> str2 >> b;
find_block(a, pile_a, height_a);    //找到a的位置
find_block(b, pile_b, height_b);    //找到b的位置
if(pile_a == pile_b)                //非法指令 忽略
continue;
if(str1 == "move" && str2 == "onto")        //move a onto b
{
clear_above(pile_a, height_a);
clear_above(pile_b, height_b);
pile_onto(pile_a, height_a, pile_b);
}
else if(str1 == "move" && str2 == "over")   //move a over b
{
clear_above(pile_a, height_a);
pile_onto(pile_a, height_a, pile_b);
}
else if(str1 == "pile" && str2 == "onto")   //pile a onto b
{
clear_above(pile_b, height_b);
pile_onto(pile_a, height_a, pile_b);
}
else if(str1 == "pile" && str2 == "over")   //pile a over b
pile_onto(pile_a, height_a, pile_b);
//        上述步骤(容易理解)可发现步骤规律 可简化如下:
//        if(str1 == "move")
//            clear_above(pile_a, height_a);
//        if(str2 == "onto")
//            clear_above(pile_b, height_b);
//        pile_onto(pile_a, height_a, pile_b);
}
print();            //最后输出
return 0;
}
题意:从左到右有n个木块,编号0~n-1,要求模拟以下4种操作(下面a和b都是木块的操作)。
move a onto b: 把a和b上方的木块全部归位,然后把a摞在b上面。
move a over b: 把a上方的木块全部归位,然后把a放在b所在木块堆得顶部。
pile a onto b: 把b上方的木块全部归位,然后把a及上面的木块整体摞在b上面。
pile a over b:把a及上面的木块整体摞在b所在木块的顶部。
所有操作结束后,输出每个位置的木块列表,按照从底部到顶部的顺序排列。
题解:用vector<int> block[maxn]做核心。具体算法竞赛入门经典。一开始find_block函数两个for循环用的pile和height又在前面用int定义了(for(int pile = 0; pile < n; pile ++)) 导致错误。 string用空格和回车都表示结束。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: