1. 程式人生 > 實用技巧 >木塊問題(The Blocks Problem. UVa 101)

木塊問題(The Blocks Problem. UVa 101)

從左到右有n個木塊,編號為0-n-1,要求模擬以下4種操作(下面a和b都是木塊編號)。

  • move a onto b: 把a和b上方的木塊全部歸位,然後把a摞到b上面。
  • move a over b: 把a上方的木塊全部歸位,然後把a及上面的木塊整體摞到b上面。
  • pile a onto b: 把b上方的木塊全部歸位,然後把a及a上面的木塊摞在b上面。
  • pile a over b: 把a及上面的木塊整體摞在b所在木塊堆的頂部。

遇到quit 時終止一組資料。a和b在同一堆的指令是非法指令,應當忽略。

所有操作結束後,輸出每個位置的木塊列表,按照從底部到頂部的順序排列。

分析:

每個木塊堆的高度不確定,所以用vector來儲存很合適;而木塊堆的個數不超過n,所以用一個數組來存就可以了。

然後,可以把4個操作總結為:

當出現move時,會把a全部歸位;當出現onto時,會把b全部歸位。

程式碼如下:

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

const int maxn = 30;
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; } } } } //把第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); //pile只應保留下標0-h的元素 } //把第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){ int pa,pb,ha,hb; find_block(a,pa,ha); find_block(b,pb,hb); if(pa == pb) continue; if(s2 == "onto") clear_above(pb,hb); if(s1 == "over") clear_above(pa,ha); pile_onto(pa,ha,pb); } print(); return 0; }

也可以選擇除錯模式,來觀察下,程式碼如下:

    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){
        if(s1 == "quit" || s2 == "quit"){
            break;
        }
        int pa,pb,ha,hb;
        find_block(a,pa,ha);
        printf("pa:%d,ha:%d \n",pa,ha);
        find_block(b,pb,hb);
        printf("pb:%d,hb:%d \n",pb,hb);
        if(pa == pb) continue;
        if(s2 == "onto"){
            clear_above(pb,hb);
            printf("onto: \n");
            print();
        }
        if(s1 == "move"){
            clear_above(pa,ha);
            printf("move: \n");
            print();
        }
        pile_onto(pa,ha,pb);
        printf("pile onto: \n");
        print();
    }
    print();
    return 0;

題目地址