看了看紫书上代码分析:收获不少!
解这个题用到了Vector类(非常巧妙简单):
整体思路:定义一耳光Vector容器:vector<int>pile[maxn];这样pile算是一个二维数组,一维是确定的(一维相当于有多少个箱子),二维是不确定的(二维相当于箱子的高度),可以放一个箱子,高度就加1来判断!(判断“高度”用到了.size() 获取高度,没有数字便是0,而不是垃圾值,非常人性化)
而放箱子用到了.push_back(数值)这个函数,本意是向数组最后加上特定的值。
最后回归原位,就是把高的箱子变小 也就是缩小空间(用到了.resize(数值))
收获的经验:
以后做题会有很多多种情况的题,最好不要把所有情况全列举出来,而是分析各个数据的共同点,这样会减少很多重复不必要的代码!
例如书中所用到的
if (s1 == "move")clear_above(ah,as);
if (s2 == "onto")clear_above(bh,bs);
两个if 就把4种情况全包括了!
教训:
认真读好原文,自己拖了很长时间便是因为没有看到数据会有不合法的情况(也就是两个箱子在同一堆!)
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
const int maxn = 10000 + 5;
int n;
vector<int>pile[maxn];
void find_v(int a,int &b, int &c){
for (b = 0; b < n; ++b)
for (c = 0; c < pile[b].size(); ++c)
if (pile[b][c] == a)return;
}
void print(){
int i;
for (i = 0; i < n; ++i){
cout << i << ":";
for (int j = 0; j < pile[i].size(); ++j)
cout << " " << pile[i][j];
cout << "\n";
}
}
void clear_above(int bh,int bs){
for (int i = bs + 1; i < pile[bh].size(); ++i){
int num = pile[bh][i];
pile[num].push_back(num);
}
pile[bh].resize(bs + 1);
}
void move_onto(int ah,int as,int bh){
for (int i = as; i < pile[ah].size(); ++i){
pile[bh].push_back(pile[ah][i]);
}
pile[ah].resize(as);
}
int main()
{
string s1,s2;
int a,b,i,ah,as,bh,bs;
cin >> n;
for (i = 0; i < n; ++i)pile[i].push_back(i);
while(cin >> s1 && s1 != "quit" && cin >> a >> s2 >> b){
find_v(a,ah,as);
find_v(b,bh,bs);
if (ah == bh )continue;
if (s1 == "move")clear_above(ah,as);
if (s2 == "onto")clear_above(bh,bs);
move_onto(ah,as,bh);
}
print();
return 0;
}