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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

zzuli-1726:迷宫(语文功底题。。。)

發布時間:2024/4/18 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 zzuli-1726:迷宫(语文功底题。。。) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接

題目描述:

在很多 RPG (Role-playing Games) 游戲中,迷宮往往是非常復雜的游戲環節。通常來說,我們在走迷宮的時候都需要花非常多的時間來嘗試不同的路徑。但如果有了算法和計算機的幫助,我們能不能有更快的方式來解決這個問題?我們可以進行一些嘗試。
現在我們有一個 N 行 M 列的迷宮。迷宮的每個格子如果是空地則可以站人,如果是障礙則不行。在一個格子上,我們可以一步移動到它相鄰的 8 個空地上,但不能離開地圖的邊界或者跨過兩個障礙的夾縫。下圖是一個移動規則的示例。

為了離開迷宮,我們還需要觸發迷宮中所有的機關。迷宮里總共有 K 個機關,每個機關都落在一個不同的空地上。如果我們到達了某個機關所在的格子時,這個機關就會被自動觸發,并在觸發之后立即消失。我們的目標是按順序觸發所有的 K 個機關,而當最后一個機關被觸發時,我們就可以離開迷宮了。
現在我們已經拿到了迷宮地圖,并且知道所有障礙、機關的位置。初始時我們位于迷宮的某個非障礙格子上,請你計算我們最少需要移動多少步才能離開迷宮?

輸入:

輸入的第一行是測試數據的組數 T (T ≤ 20)。
對于每組測試數據:第一行包含地圖的行數 N (2 ≤ N ≤ 100),列數 M(2 ≤ M ≤ 100) 和機關的數量 K(1 ≤ K ≤10)。接下來 N 行,每行包含 M 個字符,其中字符 ‘#’ 表示障礙,而 ‘.’ 表示空地。接下來一行描述了我們的初始位置 (x, y),表示我們一開始在第 x 行第 y 列的格子上。這個格子保證是個空地。接下來 K 行,每行給出了一個機關的位置。所有的機關都不會出現在障礙上,并且任意兩個機關不會出現在同一個空地上。我們需要按輸入給定的順序觸發所有的 K 個機關。

輸出:

對于每組測試數據,輸出離開迷宮所需要的最少步數。如果無論如何都不能離開迷宮,輸出 -1。

樣例輸入:

3
3 3 2



1 1
1 3
2 2
3 3 1

.#.

1 1
3 3
2 3 1
..#
.#.
1 1
2 3

樣例輸出

3
3
-1

思路:

  • 因為要按順序觸發所有機關才能出去,所以沒有輪到的機關,不能走那一格(題目中說:自動觸發,立即消失)
  • 雖然起點不會是障礙,但是可能是機關。如果是機關1就繼續搜索,如果是其他機關就注定走不出迷宮。

ac代碼:

#include<iostream> #include<string.h> #include<queue> #include<cmath> #define N 105 using namespace std; int n, m, k; char g[N][N]; struct ac{int x, y, step; }a[N]; int now_x, now_y; int vis[N][N]; int dx[8]={0, 0, -1, 1, -1, -1, 1, 1}; int dy[8]={1, -1, 0, 0, 1, -1, 1, -1}; int bfs(char target){queue<ac> que;que.push((ac) {now_x, now_y, 0});memset(vis, 0, sizeof(vis));vis[now_x][now_y] = 1;while(!que.empty()) {ac t;t = que.front();que.pop();for(int i = 0; i < 8; i++) {int xx = t.x + dx[i];int yy = t.y + dy[i];if(!vis[xx][yy] && xx >= 1 && xx <= n && yy >= 1 && yy <=m && (g[xx][yy] == '.' || g[xx][yy] == target)) { //判斷下一個點是否越界,合理 if(abs(dx[i]) + abs(dy[i]) == 2 && g[xx][t.y] == '#' && g[t.x][yy] == '#') { //判斷夾縫 continue;}if(g[xx][yy] == target) { //找到機關now_x = xx, now_y =yy; //更新當前點 g[xx][yy] = '.'; //觸發過的機關變成陸地 return t.step + 1; //返回步數 }else{que.push((ac){xx, yy, t.step + 1});vis[xx][yy] = 1;}}} }return -1; //找不到目標,返回 -1 } int main (){ios::sync_with_stdio(false);cin.tie(0);int t;cin >> t;while(t--){cin >> n >> m >> k;for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j++){cin >> g[i][j];} } cin >> now_x >> now_y; //現在的位置 for(int i = 1; i <= k; i++) {int x, y;cin >> x >> y;g[x][y] = i + '0'; //將機關標記在地圖上 } int ans = 0;for(int i = 1; i <= k; i++) {if(i == 1 && g[now_x][now_y] != '.'){ //如果起點是機關,分兩種情況 if(g[now_x][now_y] == '1'){ //起點為第一個機關,則直接觸發,并繼續搜索 g[now_x][now_y] = '.';continue;}else{ //起點是其他機關,則不可能按順序觸發所有機關 ans = -1; //直接退出 break;}} int tt = bfs(i + '0');if(tt == -1){ //找不到機關就退出 ans = -1;break;}ans += tt;} cout << ans << endl; } return 0; }

總結

以上是生活随笔為你收集整理的zzuli-1726:迷宫(语文功底题。。。)的全部內容,希望文章能夠幫你解決所遇到的問題。

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