OJ題目 推箱子

2021-08-25 09:00:36 字數 3758 閱讀 1087

大家一定玩過「推箱子」這個經典的遊戲。具體規則就是在乙個n*m的地圖上,有1個玩家、1個箱子、1個目的地以及若干障礙,其餘是空地。玩家可以往上下左右4個方向移動,但是不能移動出地圖或者移動到障礙裡去。如果往這個方向移動推到了箱子,箱子也會按這個方向移動一格,當然,箱子也不能被推出地圖或推到障礙裡。當箱子被推到目的地以後,遊戲目標達成。現在告訴你遊戲開始是初始的地圖布局,請你求出玩家最少需要移動多少步才能夠將遊戲目標達成。

輸入描述:

每個測試輸入包含1個測試用例:

第一行輸入兩個數字n,m表示地圖的大小。其中

0m<=

8 0

m<=8。

接下來有n行,每行包含m個字元表示該行地圖。其中 . 表示空地、x表示玩家、*表示箱子、#表示障礙、@表示目的地。

每個地圖必定包含1個玩家、1個箱子、1個目的地。

輸出描述:

輸出乙個數字表示玩家最少需要移動多少步才能將遊戲目標達成。當無論如何達成不了的時候,輸出-1。

輸入例子1:

4 4

…. ..*@

…. .x..

6 6

…#..

…… #*##..

..##.#

..x…

.@#…

輸出例子1:

3

11

該題目採用bfs的基本思想,對於箱子的每個位置,求小人到**中任意可達位置的最短路徑;當箱子位於終點時,問題解決,若深度優先遍歷結束時,還未到達終點,則無解;

**如下:

#pragma once

#include

#include

#include

using

namespace

std;

struct record

;struct treenode

pair pos;

record record;

};//file* freopenwrap(char const* _filename, char const* _mode, file* _oldstream);

pair operator+(pair a, pair b);

void findmazeentry(vector

>& maze,

pair &entrypos,

pair& boxpos);

bool validpos(pair a, vector

>& maze);

int bfstofindleaststep(vector

>& maze);

record::record(int step, pair pos)

record& record::operator=(record r)

bool record::checkrecord(list

& recordlist, record currecord)

else }}

// 新紀錄

recordlist.push_back(currecord);

return

true;

}//file * freopenwrap(char const * _filename, char const * _mode, file * _oldstream)

////

pair operator+(pair a, pair b)

void findmazeentry(vector

>& maze, pair& entrypos,

pair& boxpos)

if (maze[i][j] == '*')}}

}bool validpos(pair a, vector

>& maze)

return

true;

}int bfstofindleaststep(vector

>& maze)

pair direction[4] = ;

// 建立移動記錄

int n = (int)maze.size();

int m = (int)maze[0].size();

vector

>> recordmaze(n, vector

>(m));

stack

*frontstack = new

stack

; stack

*backstack = new

stack

; // 當前記錄

pair entrypos;

pair initboxpos;

findmazeentry(maze, entrypos, initboxpos);

int curstep = 0;

// 初始化迴圈條件

record currecord(curstep, initboxpos);

pair curpos;

pair nextpos;

frontstack->push(treenode(entrypos, currecord));

// 遍歷堆疊

while (1)

// 出棧

treenode node = frontstack->top();

frontstack->pop();

curpos = node.pos;

currecord = node.record;

if (curpos.first == 1 && curpos.second == 2)

// 檢查當前記錄是否有效

if (!record::checkrecord(recordmaze[curpos.first][curpos.second], currecord))

continue;

// 分情況討論

for (int i = 0; i < 4; i++)

//箱子;沒必要進入switch

if (nextpos == currecord.boxpos)

// 箱子到達終點

if (maze[nextboxpos.first][nextboxpos.second] == '@')

// 走一步,箱子也動

if (maze[nextboxpos.first][nextboxpos.second] != '#')

continue;

}switch (maze[nextpos.first][nextpos.second])}}

return -1;

}#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

int main()

for (int i = 0; ifor (int j = 0; j < m; j++)

}//for (int i = 0; i//

// cout << endl;

//}cout

<< bfstofindleaststep(maze) << endl;

}/*freopenwrap("con", "r", stdin);

system("pause");*/

}

推箱子遊戲

大一寒假 1.寫 時我犯了乙個很大的錯誤 不然早就搞定了 把 與 混淆了 大忌啊 2.這裡實現了數位化編碼 3.上72 下80 左75 右77 4.特殊圖形可以到qq拼音符號裡獲取 include include include define x 1 人的位置 define y 5 define n...

推箱子遊戲

本專案開發環境為vs2017 c 對推箱子遊戲的觀察可以發現,該遊戲就是在乙個頁面對進行移動的操作。因此可以定義乙個二維陣列map,進行初始化。0 空地 1 牆壁 3 箱子的目的地 4 箱子 6 人 7 箱子與目的地重合 9 人在箱子目的地。如下 include include include in...

C實現推箱子

推箱子遊戲編寫思路總結 1.顯示遊戲地圖 2.顯示小人移動的方向 3.移動小人 第一 簡單的介面輸出時可以用指標陣列,指標陣列map中含十個指標map 0 map 1 map 9 分別是這是個字串的起始位址 char map row 但最後改變位置時不太方便,還是使用c以二維陣列輸出比較簡潔。第二 ...