日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计蒜客题解——T1213:拯救行动

發布時間:2024/3/12 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计蒜客题解——T1213:拯救行动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目相關

題目鏈接

計蒜客 OJ,https://nanti.jisuanke.com/t/T1213。

題目描述

公主被惡人抓走,被關押在牢房的某個地方。牢房用 N×M(N,M≤200) 的矩陣來表示。矩陣中的每項可以代表道路(@)、墻壁(#)、和守衛(x)。

英勇的騎士(r)決定孤身一人去拯救公主(a)。我們假設拯救成功的表示是 "騎士到達了公主所在的位置"。由于在通往公主所在位置的道路中可能遇到守衛,騎士一旦遇到守衛,必須殺死守衛才能繼續前進。

現假設騎士可以向上、下、左、右四個方向移動,每移動一個位置需要 1 個單位時間,殺死一個守衛需要花費額外的 1 個單位時間。同時假設騎士足夠強壯,有能力殺死所有的守衛。

給定牢房矩陣,公主、騎士和守衛在矩陣中的位置,請你計算拯救行動成功需要花費最短時間。

輸入格式

1、兩個整數代表 N 和 M,(N,M≤200).
2、隨后 N 行,每行有 M 個字符。"@" 代表道路,"a" 代表公主,"r" 代表騎士,"x" 代表守衛, "#" 代表墻壁。

輸出格式

如果拯救行動成功,輸出一個整數,表示行動的最短時間。
如果不可能成功,輸出 "Impossible"。

樣例輸入1

7 8 #@#####@ #@a#@@r@ #@@#x@@@ @@#@@#@# #@@@##@@ @#@@@@@@ @@@@@@@@

樣例輸出1

13

樣例輸入2

13 40 @x@@##x@#x@x#xxxx##@#x@x@@#x#@#x#@@x@#@x xx###x@x#@@##xx@@@#@x@@#x@xxx@@#x@#x@@x@ #@x#@x#x#@@##@@x#@xx#xxx@@x##@@@#@x@@x@x @##x@@@x#xx#@@#xxxx#@@x@x@#@x@@@x@#@#x@# @#xxxxx##@@x##x@xxx@@#x@x####@@@x#x##@#@ #xxx#@#x##xxxx@@#xx@@@x@xxx#@#xxx@x##### #x@xxxx#@x@@@@##@x#xx#xxx@#xx#@#####x#@x xx##@#@x##x##x#@x#@a#xx@##@#@##xx@#@@x@x x#x#@x@#x#@##@xrx@x#xxxx@##x##xx#@#x@xx@ #x@@#@###x##x@x#@@#@@x@x@@xx@@@@##@@x@@x x#xx@x###@xxx#@#x#@@###@#@##@x#@x@#@@#@@ #@#x@x#x#x###@x@@xxx####x@x##@x####xx#@x #x#@x#x######@@#x@#xxxx#xx@@@#xx#x#####@

樣例輸出2

7

題目分析

題意分析

一個 N*M 大小的迷宮,我們從 r 位置出發(也就是起點),字符 @ 表示可以安全通行的方格,字符 # 表示墻壁(也就是不能走),字符 x 代表守衛(守衛可以殺死,但是必須付出額外的 1 個單位時間),字符 a 表示仙藥(也就是終點)。要求輸出從 @ 到 a 的最短路徑。那么迷宮問題的基本要素全齊了,所以本題就是一道 BFS 模板題。

樣例數據分析

本題和以前的 BFS 模板題唯一的不同就是所有守衛可以殺死,但是需要付出額外的時間。因此意味著 x 的地方是可以走的,只是要多付出 1 個單位時間。也就是說,走 x 地方,需要 2 個時間單位;走 @ 地方,需要 1 個時間單位。

省略。如果想看類似的數據分析,可以看以前的文章,https://blog.csdn.net/justidle/article/details/104651311。主要是我偷懶了,畫圖太累了,請原諒。

算法思路

1、讀入數據,并寫入到合適的數據結構中。

2、找到起點位置,將起點加入到隊列 q 中。

3、記錄終點位置信息。

4、開始 BFS 遍歷。直到找到終點或者遍歷所有節點而無法到達終點。注意:走 x 地方,需要 2 個時間單位;走 @ 地方,需要 1 個時間單位。

AC 參考代碼

#include <cstdio> #include <queue>//位置定義 struct POS {int x, y;//坐標int cost;//本節點到起點的距離 };const int MAXN = 202; struct MAZE {int row, col;//迷宮大小char data[MAXN][MAXN];//迷宮數據描述bool visit[MAXN][MAXN];//是否已經訪問過節點int x1, y1;//起點坐標int x2, y2;//終點坐標 };int bfs(MAZE &maze);int main() {MAZE maze = {};//迷宮定義并將所有初始化為零//讀入迷宮長寬 scanf("%d %d", &maze.row, &maze.col);//讀入迷宮數據int i,j;for (i=0; i<maze.row; i++) {for (j=0; j<maze.col; j++) {scanf(" %c", &maze.data[i][j]);if (maze.data[i][j]=='a') {//終點maze.x2 = i;maze.y2 = j; } else if (maze.data[i][j]=='r') {//起點maze.x1 = i;maze.y1 = j; }}} int ans = bfs(maze);if (ans>0) {printf("%d\n", ans);} else {printf("Impossible\n");}return 0; }int bfs(MAZE &maze) {std::queue<POS> q;//下一個節點隊列const POS move[] = {{-1,0}, {0,1}, {1,0}, {0,-1}};//騎士的移動方法POS cur;//當前位置POS next;//下一個位置//加入起點cur.x = maze.x1;cur.y = maze.y1;cur.cost = 0;maze.visit[cur.x][cur.y] = true;//設置本節點已經訪問q.push(cur); //開始遍歷while (!q.empty()) {//彈出隊首節點cur = q.front();q.pop();if (maze.data[cur.x][cur.y]=='x') {//由于有干掉守衛,所以我們我們先加入的不一定是最小的maze.data[cur.x][cur.y]='@';cur.cost++;q.push(cur);} else {for (int i=0; i<4; i++) {next.x = cur.x + move[i].x;next.y = cur.y + move[i].y;//判斷是不是終點if (next.x==maze.x2 && next.y==maze.y2) {return cur.cost + 1;} //判斷通過性if (next.x>=0&&next.x<maze.row&&next.y>=0&&next.y<maze.col&&maze.visit[next.x][next.y]==false&&maze.data[next.x][next.y]!='#') {next.cost = cur.cost + 1;maze.visit[next.x][next.y] = true;q.push(next);}}}}return -1; }

代碼分析

1、如何表示一個節點的坐標,以及該節點到起點的距離。這里我用一個自定義的結構體來表示。如下所示:

struct POS {int x, y;//當前結點坐標int cost;//從起點到當前結點的距離 };

2、如何表示一個迷宮。這里我將所有迷宮信息全部放在一個自定義結構體中,增強了代碼可讀性。如下所示:

const int MAXN = 200; struct MAZE {int m, n;//迷宮大小char data[MAXN][MAXN];//迷宮的數據bool visit[MAXN][MAXN];//是否已經走過int x1, y1;//起點信息int x2, y2;//終點信息 };

3、如何表示所有移動可能性。如下所示:

const POS move[] = {{-1,0}, {0,1}, {1,0}, {0,-1}};//定義移動方法

4、新節點通過性判斷問題。根據題目進行判斷,基本包括以下幾個方面:

(1)這個位置可以走,如本題中用字符 . 表示。如下所示:

maze.data[next.x][next.y]!='#'

注意,只要不是 # 就認為這個節點是可以走的。至于是否是守衛,我們等彈出的時候再判斷。這個細節是和標準走迷宮不一樣的。

(2)這個位置沒有訪問過。如下所示:

maze.visit[next.x][next.y]==false

(3)這個位置處于迷宮內。這個判斷和您程序對迷宮定義有關。如下所示:

next.x>=0&&next.x<maze.m&&next.y>=0&&next.y<maze.n

(4)判斷這個位置是不是守衛。在彈出隊首元素的時候才判斷。如下所示:

if (maze.data[cur.x][cur.y]=='x') {//由于有干掉守衛,所以我們我們先加入的不一定是最小的maze.data[cur.x][cur.y]='@';cur.cost++;q.push(cur); }

當然,也可以在走到本位置的時候進行判斷。不管在哪里判斷,是不會影響結果的,這是由于 BFS 的特性決定的。

總結

以上是生活随笔為你收集整理的计蒜客题解——T1213:拯救行动的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。