UVA - 101:The Blocks Problem
原本以為是一道很簡(jiǎn)單的模擬題,結(jié)果寫了一個(gè)小時(shí)。。。很長(zhǎng)時(shí)間不碰算法題,的確手感差很多。不過我覺得隨著刷題慢慢多起來應(yīng)該會(huì)好的。
題目的意思也有點(diǎn)含糊,需要自己去猜,大概意思就是槽里有一堆木頭,每個(gè)槽剛開始的時(shí)候只有一個(gè),需要移過來移過去,有四種方式,這四種方式都是針對(duì)木頭而言的,因此我們必須時(shí)刻記錄每個(gè)木頭的位置。當(dāng)然還需要數(shù)據(jù)結(jié)構(gòu)記錄槽的狀態(tài),最后需要輸出。
四種移動(dòng)方式有一些是共通的,因此需要將其抽象成函數(shù),我這里抽象了三個(gè)函數(shù):
void ret_block(int x);將木頭x頭頂?shù)哪绢^歸還到原本的槽里面(i號(hào)木頭到i號(hào)槽)
void mve(int x, int idx);將木頭x移動(dòng)到槽idx的位置,之所以不叫move是因?yàn)椴幌牒蜆?biāo)準(zhǔn)庫(kù)的move函數(shù)沖突
void pile(int x, int idx);將木頭x以及其頭頂?shù)乃心绢^移動(dòng)到槽idx
雖然使用三個(gè)函數(shù)簡(jiǎn)化了四種操作,但是我覺得自己分離的不夠清晰,按道理講pile函數(shù)應(yīng)該調(diào)用mve函數(shù),因?yàn)橐粋€(gè)是移動(dòng)一個(gè)木頭,一個(gè)是移動(dòng)一堆木頭,可是因?yàn)槭褂玫氖莢ector,導(dǎo)致無法隨機(jī)插入。
順帶吐槽一下:我為了控制不輸出最后的換行專門寫了一個(gè)Newline函數(shù)類,但是直接報(bào)錯(cuò)。。有的OJ要求不能有,有的又要求必須有。。
看了一下別人的題解,有兩點(diǎn)收獲:
- 不用判斷整個(gè)字符串再確定是什么命令,判斷一下首字母就可以了
- 可以使用erase函數(shù)整塊刪除。自己就是因?yàn)椴恢肋@個(gè)函數(shù)寫的比較復(fù)雜,還是要對(duì)STL更加熟悉才行
再研究了一下書上的題解,發(fā)現(xiàn)果然pile函數(shù)可以和move函數(shù)合并,而且可是使用resize函數(shù)進(jìn)行刪除。
對(duì)于這種多種指令的,我們要提取出指令之間的共同點(diǎn),編寫函數(shù)以減少重復(fù)代碼。
#include <iostream> #include <vector> #include <string> #include <array>using namespace std;namespace {const string QUIT = "quit";const string MOVE = "move";const string ONTO = "onto";const string OVER = "over";const string PILE = "pile";constexpr int MAXN = 25 + 5;array<vector<int>, MAXN> blocks;array<pair<int, int>, MAXN> pos;int n; }void init() {cin >> n;for (int i = 0; i < n; ++i) {blocks[i].push_back(i);pos[i] = {i, 0};} }void mve(int x, int idx) {blocks[idx].push_back(x);blocks[pos[x].first].pop_back();pos[x].first = idx;pos[x].second = blocks[idx].size() - 1; }void pile(int x, int idx) {auto &block_x = blocks[pos[x].first];auto &block_dst = blocks[idx];int origin_pos = pos[x].second;int y;for (int i = origin_pos; i < block_x.size(); ++i) {y = block_x[i];block_dst.push_back(y);pos[y].first = idx;pos[y].second = block_dst.size() - 1;}for (int i = block_x.size() - 1; i >= origin_pos; --i) block_x.pop_back(); }void ret_block(int x) {//return blocks that are stacked on top of xauto &block_x = blocks[pos[x].first];int y;for (int i = block_x.size() - 1; i > pos[x].second; --i) {y = block_x.back();mve(y, y);} }void work() {int x, y;string action, prep;while (cin >> action) {if (action == QUIT) break;cin >> x >> prep >> y;if (pos[x].first == pos[y].first) continue;if (action == MOVE) {if (prep == ONTO) {//move x onto yret_block(x);ret_block(y);mve(x, pos[y].first);} else {ret_block(x);mve(x, pos[y].first);}} else {if (prep == ONTO) {ret_block(y);pile(x, pos[y].first);} else {pile(x, pos[y].first);}}} }class Newline {bool first; public:Newline(bool _fisrt = true):first(_fisrt) {}inline void operator ()(); };inline void Newline::operator()() {if (first) {first = false;} else {cout << "\n";} }void print() {Newline newline;for (int i = 0; i < n; ++i) {//newline();cout << i << ":";for (auto x : blocks[i]) {cout << " " << x;}cout << "\n";} }int main() {ios::sync_with_stdio(false);init();work();print(); }總結(jié)
以上是生活随笔為你收集整理的UVA - 101:The Blocks Problem的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++输入输出:cin/cout 还是
- 下一篇: UVA - 12096:The SetS