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