这是一道很好的模拟题,用vector<int> p[maxn],建立模型,映射为maxn个堆。主要要掌握vector模拟堆操作的简单方法。
接下来得思路是自顶向下的方式,逐步完善程序。首先根据提议列出下表。
1.move a onto b
clear_above(a) && clear_above(b);
insert a above b;
2.move a over b
clear(a)
insert a above bs
3.pile a onto b
clear(b)
insert as above b
4.pile a over b
insert as above bs
观察可以提取出move的话必有clear_above(a)、onto必有clear_above(b).
而insert 动作不管b是在p[b]的顶部还是外部。都是p[b].push_back(a或a以上的木块)
所以可以抽取成pile_into(pa, ha, pb);
考虑完这些,开始写框架。如下
1
2 #include <cstdio>
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 using namespace std;
7
8 const int maxn = 64;
9 int n;
10 vector<int> a[maxn];
11 int find_block(int a, int& h);
12 void clear_above(int p, int h);
13 void pile_into(int pa, int ha, int pb);
14 void print();
15 int main() {
16
17
18
19 string s1, s2;
20 scanf("%d", &n);
21 for (int i = 0; i < n ; i++) {
22 a[i].push_back(i);
23 }
24
25 while (cin >> s1, s1 != "quit") {
26 int ba,bb;
27 cin >> ba >> s2 >> bb;
28 int ha = 0,hb = 0;
29 int pa = find_block(ba, ha);
30 int pb = find_block(bb, hb);
31 if (pa == pb) continue;
32
33 if (s1 == "move") clear_above(pa, ha);
34 if (s2 == "onto") clear_above(pb, hb);
35 pile_into(pa, ha, pb);
36 }
37
38 print();
39 return 0;
40 }
接下来,完成程序其它部分,按照框架的意思,逐步完善。如下
1 void print() {
2
3 for (int i = 0; i < n; i++) {
4 printf("%d:",i);
5 for (int h = 0; h < a[i].size(); h++) {
6 printf(" %d", a[i][h]);
7 }
8 printf("\n");
9 }
10 }
11
12 int find_block(int ba, int& h) {
13
14 for (int i = 0; i < n; i++) {
15
16 int vec_size = a[i].size();
17 for (h = 0; h < vec_size; h++) {
18 if (ba == a[i][h]) return i;
19 }
20
21 }
22 return -1;
23 }
24
25 void clear_above(int p, int h) {
26 int vec_size = a[p].size();
27 for (int i = h + 1; i < vec_size; i++) {
28
29 int b = a[p][i];
30 a[b].push_back(b);
31
32 }
33 a[p].resize(h + 1);
34 }
35
36 void pile_into(int pa, int ha, int pb) {
37
38 int vec_size = a[pa].size();
39
40 for (int i = ha; i < vec_size; i++) {
41 a[pb].push_back(a[pa][i]);
42 }
43 a[pa].resize(ha);
44 }