1. 程式人生 > 其它 >ACM H-8 廣度優先搜尋(BFS)

ACM H-8 廣度優先搜尋(BFS)

技術標籤:c++ACMBFS佇列bfsc語言

最近在家上網課的zst由於把switch放在了寢室所以實在無聊透頂,便拉著str一起玩一款名叫《風來的西林》的遊戲,在某次刷圖的過程中,由於zst炸裂的歐氣,一張地圖中同時出現了數把螺旋風魔劍,但此劍需要zst和str兩人合力才可取得。

由於這款遊戲是按時間付費的,所以兩人需要儘快取得此劍(即為二人到達劍所在位置的時間之和最少),因此他們找到了機智的你來幫忙解決問題。

Input

多組資料讀入到檔案結束
每組資料的第一行輸入兩個整數n, m(2 <= n, m <= 200),即迷宮大小為n*m
接下來n行,每行包括m個字元
'Y'表示zst所在位置
'M'表示str所在位置
'.'表示可以行走的道路
'#'表示不可通過的牆壁
'@'表示螺旋風魔劍所在位置(數量多於一把)
二人每次行動只有上下左右四種方式,每次行動花費11個單位時間

Output

每組樣例輸出一行一個整數:二人到達同一把劍所在位置的最小時間之和。
保證有解

Sample Input

3 3
[email protected]
#..
@.M

Sample Output

44

注意: 有一個測試點是劍周圍都是牆體無法拿取。

#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
char map[202][202];//地圖 
int n,m;//n*m的陣列 
int a[202][202],b[202][202];//分別對應Y,M兩個人 
int yidong[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//移動陣列,對應上下右左 struct node{ int x,y; }; bool pd(int x,int y,int luxian[202][202])//判斷能否移動 { if(x<0||x>=n||y<0||y>=m)//判斷邊界 return false; if(luxian[x][y]!=0)//判斷是否走過 return false; if(map[x][y]=='#')//判斷是否能通行 return false; return true; } void bfs(int
x,int y,int luxian[202][202])//廣度優先搜尋(BFS) { queue<node>q;//建立佇列 node next,last;//建立next為此佇列值,last為前一個佇列值 next.x=x;next.y=y;//對此佇列值賦值 luxian[x][y]=0; q.push(next);//放入佇列 while(!q.empty())//不為空就繼續 { last=q.front();//計入佇列頭的值 q.pop();//推出 for(int i=0;i<4;i++)//上下左右四個方向移動 { next.x=last.x+yidong[i][0];//x移動值 next.y=last.y+yidong[i][1];//y移動值 if(pd(next.x,next.y,luxian))//判斷是否能走 { luxian[next.x][next.y]=luxian[last.x][last.y]+1;//沿路做標記 q.push(next);//放入佇列 } } } } int main() { int i,j,ydmin,yx,yy,mx,my; while(cin>>n>>m)//此題為多組輸入 { ydmin=1000000;//哨兵 memset(a,0,sizeof(a));//來自string標頭檔案 memset(b,0,sizeof(b));//因為多組輸入所以要對a,b陣列清空處理 for(i=0;i<n;i++) { for(j=0;j<m;j++) { cin>>map[i][j]; if(map[i][j]=='Y')//記錄Y地址 { yx=i;yy=j; } else if(map[i][j]=='M')//記錄M地址 { mx=i;my=j; } } } bfs(yx,yy,a);//Y開始廣搜 bfs(mx,my,b);//M開始廣搜 for(i=0;i<n;i++) { for(j=0;j<m;j++) { if(map[i][j]=='@'&&a[i][j]!=0)//有一個測試點是a[i][j]+b[i][j]=0 { ydmin=min(ydmin,a[i][j]+b[i][j]); } } } cout<<ydmin*11<<endl; } return 0; }