一个FLAG #10# The Blocks Problem

例题5-2 木块问题。要区分onto和over,onto是要a与b直接接触,over则不需要。以及,move某木块时,要把它上面的木块全部归位,而pile某木块则不需要。

#include <cstdio>
#include <string>
#include <vector>
#include <iostream>
using namespace std;

const int maxn = 20;
int n;
vector<int> pile[maxn]; // 每个pile[i]是一个vector

// 找木块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; // vector也可以用数组的形式访问! 
        }
    }
} 

// 把第p堆高度为h的木块上方的所有木块移回原位 
void clear_above(int p, int h)
{
    for (int i = h + 1; i != pile[p].size(); ++i) {
        int b = pile[p][i];
        pile[b].push_back(b);     
    }
    pile[p].resize(h + 1); // 只保留 0~ h的位置。不包括h+1!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); // 只保留0~ h-1的位置。 
} 

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("
");
    }
}

int main()
{
    int a, b;
    cin >> n; // 有n 个木块 
    string s1, s2;
    for (int i = 0; i != n ; ++i) {
        pile[i].push_back(i);
    }
    while (cin >> s1 >> a >> s2 >> b) {
        // 例如读入 move 1 onto 2 
        int pa, pb, ha, hb;
        find_block(a, pa, ha);
        find_block(b, pb, hb);
        // 此时 pa ha 存储着 a所在堆的编号 以及高度 
        // 同理 pb hb 存储着 b所在堆的编号 以及高度  
        if (pa == pb) continue; // a 与 b 在同一堆的指令是非法指令 
        if (s2 == "onto") clear_above(pb, hb); // onto要把 b 上的木块归位 
        if (s1 == "move") clear_above(pa, ha); // move 要把 a 上的木块归位 
        pile_onto(pa, ha, pb);
    }
    print();
    return 0;
}
/*
Sample Input

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
^Z

Sample Output

0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:
*/

参考

[1] The Blocks Problem(vector) - 若流芳千古 - 博客园

[2] C++ vector 容器浅析 | 菜鸟教程

原文地址:https://www.cnblogs.com/xkxf/p/12649675.html