UVa101
n
个带有编号的石块排成一排,根据命令移动石块:
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
的那一摞上
如果a
和b
相同或者a
和b
在同一摞,则跳过此命令。
显然石块应该使用二维数组存储,麻烦的是如何知道当前状态下石块的位置,这可以通过使用另外的数组记录每个石块当前的位置并在处理命令的过程中维护位置信息即可。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void MoveOnto(vector<vector<int>> &blocks, vector<int> &position, int a, int b)
{
int apos = position[a], bpos = position[b], top;
if (a == b || apos == bpos) return;
while (!blocks[apos].empty() && ((top = blocks[apos].back()) != a)) {
blocks[apos].pop_back();
blocks[top].push_back(top);
position[top] = top;
}
while (!blocks[bpos].empty() && ((top = blocks[bpos].back()) != b)) {
blocks[bpos].pop_back();
blocks[top].push_back(top);
position[top] = top;
}
blocks[bpos].push_back(a);
blocks[apos].pop_back();
position[a] = bpos;
}
void MoveOver(vector<vector<int>> &blocks, vector<int> &position, int a, int b)
{
int apos = position[a], bpos = position[b], top;
if (a == b || apos == bpos) return;
while (!blocks[apos].empty() && ((top = blocks[apos].back()) != a)) {
blocks[apos].pop_back();
blocks[top].push_back(top);
position[top] = top;
}
blocks[bpos].push_back(a);
blocks[apos].pop_back();
position[a] = bpos;
}
void PileOnto(vector<vector<int>> &blocks, vector<int> &position, int a, int b)
{
int apos = position[a], bpos = position[b], top;
if (a == b || apos == bpos) return;
while (!blocks[bpos].empty() && ((top = blocks[bpos].back()) != b)) {
blocks[bpos].pop_back();
blocks[top].push_back(top);
position[top] = top;
}
vector<int> tmp;
while (!blocks[apos].empty() && ((top = blocks[apos].back()) != a)) {
tmp.push_back(top);
blocks[apos].pop_back();
}
tmp.push_back(a);
blocks[apos].pop_back();
while (!tmp.empty()) {
blocks[bpos].push_back(tmp.back());
position[tmp.back()] = bpos;
tmp.pop_back();
}
}
void PileOver(vector<vector<int>> &blocks, vector<int> &position, int a, int b)
{
int apos = position[a], bpos = position[b], top;
if (a == b || apos == bpos) return;
vector<int> tmp;
while (!blocks[apos].empty() && ((top = blocks[apos].back()) != a)) {
tmp.push_back(top);
blocks[apos].pop_back();
}
tmp.push_back(a);
blocks[apos].pop_back();
while (!tmp.empty()) {
blocks[bpos].push_back(tmp.back());
position[tmp.back()] = bpos;
tmp.pop_back();
}
}
int main()
{
int n = 0;
cin >> n;
vector<vector<int>> blocks;
vector<int> position;
for (int i = 0; i < n; i++)
{
blocks.push_back(vector<int>());
blocks.back().push_back(i);
position.push_back(i);
}
string command, a, prep, b;
while (cin >> command) {
if (command == "quit") break;
else if (command == "move") {
cin >> a >> prep >> b;
if (prep == "onto") {
MoveOnto(blocks, position, stoi(a), stoi(b));
}
else if (prep == "over") {
MoveOver(blocks, position, stoi(a), stoi(b));
}
else;
}
else if (command == "pile") {
cin >> a >> prep >> b;
if (prep == "onto") {
PileOnto(blocks, position, stoi(a), stoi(b));
}
else if (prep == "over") {
PileOver(blocks, position, stoi(a), stoi(b));
}
else;
}
else;
}
for (size_t i = 0; i < blocks.size(); i++)
{
cout << i << ":";
for (size_t j = 0; j < blocks[i].size(); j++)
{
cout << ' ' << blocks[i][j];
}
cout << endl;
}
return 0;
}
/*
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
*/