【NOJ1009】【演算法實驗二】【DFS_回溯】迷宮問題
阿新 • • 發佈:2018-12-12
1009.迷宮問題
時限:1000ms 記憶體限制:10000K 總時限:3000ms
描述
給一個20×20的迷宮、起點座標和終點座標,問從起點是否能到達終點。
輸入
多個測例。輸入的第一行是一個整數n,表示測例的個數。接下來是n個測例,每個測例佔21行,第一行四個整數x1,y1,x2,y2是起止點的位置(座標從零開始),(x1,y1)是起點,(x2,y2)是終點。下面20行每行20個字元,’.’表示空格;’X’表示牆。
輸出
每個測例的輸出佔一行,輸出Yes或No。
【第二版程式碼】學會了一個用陣列計算新格子橫縱座標的方法,不需要用switch判斷具體方向和複雜的false條件,又重寫了moveto函式,去掉了冗餘的canmoveto函式,使程式碼更加簡潔美觀啦。(第一版刪掉了太丟臉了)
#include <iostream> using namespace std; char maze[20][20]; //存放迷宮 //X==牆 //.==空 //1==已經走過 int n; int sx,sy; //start int tx,ty; //target int walk[4][2]= //走一格後橫縱座標變化 { 0, -1, //左 +1, 0, //下 0, +1, //右 -1, 0 //上 }; void dfs(int m); //從第m個格子出發開始深搜 int moveto(int x, int y, int d); //從格子[x][y]能否向方向d走一步 //若能,返回next格子序號 //若不能,返回-1 int main() { cin>>n; while(n--) { //輸入資料 cin>>sx>>sy>>tx>>ty; cin.get(); //重點!不要忘記吃第一行末尾的換行符 for(int i=0; i<20; i++) { for(int j=0; j<20; j++) { maze[i][j]=cin.get(); } cin.get(); //吃掉每一行末尾的換行符 } //演算法執行 dfs(sx*20+sy); //輸出資料 if(maze[tx][ty]=='1') { cout<<"Yes"<<endl; } else { cout<<"No"<<endl; } } return 0; } void dfs(int m) //從第m個格子出發搜尋 { int x=m/20; int y=m%20; maze[x][y]='1'; //標記已經到達 int next; for(int d=0; d<4; d++) //向4個方向試探,0==左,1==下,2==右,3==上 { next=moveto(x, y, d); //若能向d方向走,就返回走一步後的格子序號next if(next>=0) //若不能向d方向走,moveto函式返回給next的值是-1 { dfs(next); } } } //越界判斷、是牆判斷、重複判斷 int moveto(int x, int y, int d) //從格子[x][y]能否向方向d走一步 { int nextx=x+walk[d][0]; //獲取新座標 int nexty=y+walk[d][1]; if(nextx<20&&nextx>=0&&nexty<20&&nexty>=0) //不越界 { if(maze[nextx][nexty]=='.') //不是牆且不重複 { return (nextx*20+nexty); //返回新格子序號 } } return -1; //無法通行,返回-1 }