算法竞赛入门经典(第二版) | 例题5-2 木块问题 (紫皮书牛啤!)(UVa101,The Blocks Problem)
大意:
輸入n,代表n個木塊,輸入最多n種操作類型,按類型對木塊進行操作,讀入quit結束
輸入輸出格式:
1、move a onto b:將a和b所在上方的方塊先歸位,再將a移到b所在柱子
2、move a over b:僅將a所在上方的方塊先歸位,再將a移到b所在柱子
3、pile a onto b:將b所在上方的方塊先歸位,再將a及其上方的所有方塊移到b所在柱子
4、pile a over b:無需歸位,直接將a及其上方的所有方塊移到b所在柱子
5、quit:結束,打印輸出
6、無效指令:命令中a和b在同一柱子,直接忽略即可
分析:
本題思路不難想,但若想寫出簡潔的代碼,就需要動一番腦筋了,如何提高代碼的復用性呢?我們先歸納出重要步驟:
??1、找a和b塊
??2、若為move或onto,則a或b塊歸位
??3、將a的方塊移動到b上,
這時我們不難發現:
找a塊和b塊的代碼是相似的,因此可以寫一個函數復用;同理,將a塊歸位,與將b塊歸位也是類似的,同樣寫一個函數復用,這樣代碼就簡潔了不少。當然,print()函數也是不可或缺的,調試神器啊!詳情見第34行代碼。
題目(提交)鏈接→UVa-101
沒使用過該網站的同學請猛戳這里→vJudge教程
代碼:
#include <iostream> #include <vector> #include <cstdio> using namespace std;const int maxn = 30; int n; vector<int> pile[maxn]; //因為木塊的長度不定,所以適合用vector保存//找木塊的pile和height,以引用的形式返回(配合void) 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; //要有自信好吧!這個復雜度也是o(n3) } //把第p堆高度為h的木塊上方的所有木塊移回原位。 void clear_above(int p, int h) { //p代表行,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的元素,采用這種方法,就不需要用pop一個一個彈出了。 }//把第p堆高度為h及其上方的木塊整體移動到p2堆的頂部 void pile_onto(int p, int h, int p2) {for(int i = h; i < pile[p].size(); i++) //從塊1所在行往上截取, pile[p2].push_back(pile[p][i]); //從塊2所在列往上堆填 pile[p].resize(h); } //調試神奇print()重出江湖 void print() {for(int i = 0; i < n; i++) {printf("%d:", i);for(int j = 0; j < pile[i].size(); j++) print(" %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); //a是待移動木塊角標,pa是所在行,ha是所在列find_block(b, pb, hb); //b是最終位置角標,pb是所在行 , hb是所在列if(pa = pb) continue; //若所在行相同,則為無效移動if(s2 == "onto") clear_above(pb, hb); if(s1 == "move") clear_above(pa, ha); pile_onto(pa, ha, pb); } return 0;}收獲:
1、二維數組vector,行固定,列不固定
2、提取關鍵字:找a和b塊,歸位,將a的方塊移動到b上,都可以各提取出一個函數,進行函數復用。
3、采用自頂向下的編寫方法,函數復用技巧,調試技巧。
4、resize代替pop
總結
以上是生活随笔為你收集整理的算法竞赛入门经典(第二版) | 例题5-2 木块问题 (紫皮书牛啤!)(UVa101,The Blocks Problem)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dev-Cpp 常用的快捷键(持续更新)
- 下一篇: 简洁明了——STL容器库之set头文件常