原题摘录
输入n,得到编号为0~n-1的木块,分别摆放在顺序排列编号为0~n-1的位置。现对这些木块进行操作,操作分为四种。
1、move a onto b:把木块a、b上的木块放回各自的原位,再把a放到b上;
2、move a over b:把a上的木块放回各自的原位,再把a发到含b的堆上;
3、pile a onto b:把b上的木块放回各自的原位,再把a连同a上的木块移到b上;
4、pile a over b:把a连同a上木块移到含b的堆上。
当输入quit时,结束操作并输出0~n-1的位置上的木块情况
输入输出见文末.
题目分析
每个木块堆的高度不确定,所以用vector来保存很合适;而每个木块堆的个数不超过n,所以用一个数组来存就可以了.
vector<int> pile[maxn];//一个存储int向量的数组
分析原题中的四个操作:
归位 | 移顶 | |
move | a归位 | 均有- |
onto | b归位 | 且均为- |
即move又onto | a,b均归位 | 将a往b- |
pile/over | 无 | 放 |
发现这是个指令有很多共同点,根据这样编写的函数就会减少重复代码.也即一个归位函数和一个移顶函数以及查出位置的辅助函数.所以有时不用指令完全独立.
完整代码(详细注释)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 30;
int n;
vector<int> pile[maxn];
//找到木块a所在的pile和height,以引用的形式返回调用者
void find_block(int a, int& p, int& h)//当有一个元素时高度为0,也即h=0
{
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 m = pile[p][i];
pile[m].push_back(m);
}
pile[p].resize(h + 1);
}
//把第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)//cin >> s1&&s1 != "quit"&&cin >> a >> s2 >> b
{
int pa, pb, ha, hb;
find_block(a, pa, ha);//找到a所在的位置:pa指第几个vector-1,ha指该vector的长度-1
find_block(b, pb, hb);
if (pa == pb) continue;//非法指令
if (s2 == "onto") clear_above(pb, hb);//b归位
if (s1 == "move") clear_above(pa, ha);//a归位
pile_onto(pa, ha, pb);
}
print();
return 0;
}
附如果关于位置又不太明白的,可以仅使用find_block()函数输出一下看看:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 30;
int n;
vector<int> pile[maxn];
//找到木块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;
}
}
int main()
{
int a, b;
cin >> n;
for (int i = 0; i < n; i++)pile[i].push_back(i);
cin >> a >> b;
int pa, pb, ha, hb;
find_block(a, pa, ha);
find_block(b, pb, hb);
cout<<"pa:"<<pa<<" "<<"ha:"<<ha<<endl;
cout<<"pb:"<<pb<<" "<<"hb:"<<hb<<endl;
return 0;
}
//https://www.cnblogs.com/QG-whz/