【NOJ1042】【分支限界法】電子老鼠走迷宮
阿新 • • 發佈:2018-12-14
1042.電子老鼠闖迷宮
時限:1000ms 記憶體限制:10000K 總時限:3000ms
描述
有一隻電子老鼠被困在如下圖所示的迷宮中。這是一個12*12單元的正方形迷宮,黑色部分表示建築物,白色部分是路。電子老鼠可以在路上向上、下、左、右行走,每一步走一個格子。現給定一個起點S和一個終點T,求出電子老鼠最少要幾步從起點走到終點。(迷宮左上角為[1, 1])
輸入
本題包含一個測例。在測例的第一行有四個由空格分隔的整數,分別表示起點的座標S(x.y)和終點的座標T(x,y)。
從第二行開始的12行中,每行有12個字元,描述迷宮的情況,其中'X'表示建築物,'.'表示路.
輸出
輸出一個整數,即電子老鼠走出迷宮至少需要的步數。
#include <iostream> #include <queue> using namespace std; struct Node //用一個結構體存放當前在迷宮中的位置/狀態 { int x; //當前狀態橫座標,從1開始 int y; //當前狀態縱座標,從1開始 }; queue <Node> state; //結構體佇列 //這是自己寫的第一個結構體佇列,值得紀念,液! char maze[13][13]; //存放迷宮,從[1,1]開始 int used[13][13]; //當前格子是否已訪問過 int step[13][13]; //存放從起點走到當前格子需要走的步數 bool canmoveto(int x,int y,int d); //判斷方格[x,y]能否向方向d走一步 Node moveto(int x,int y,int d); //返回方格[x,y]向d走一步之後到達的格子node int main() { Node start,target; //起點結構體與終點結構體 cin>>start.x>>start.y>>target.x>>target.y; for(int i=1;i<=12;i++) { for(int j=1;j<=12;j++) { cin>>maze[i][j]; } } state.push(start); //起點入隊 used[start.x][start.y]=1; //標記起點訪問過 step[start.x][start.y]=0; //從起點走到起點需要0步 Node top,next; while(!state.empty()) { top=state.front(); //取隊首元素 state.pop(); for(int d=0; d<4; d++) //向四個方向試探 { if(canmoveto(top.x,top.y,d)) //如果方向d能走 { next=moveto(top.x,top.y,d); //向方向d走一步,走到next格子 used[next.x][next.y]=1; //標記next格子被訪問過 step[next.x][next.y]=step[top.x][top.y]+1; //走到next格子的步數比走到top格子的步數多一步 state.push(next); //將next入隊 //cout<<next.x<<' '<<next.y<<' '<<step[next.x][next.y]<<endl; } } if(next.x==target.x&&next.y==target.y) //如果next格子就是目標格子,那麼退出 { break; } } cout<<step[target.x][target.y]<<endl; return 0; } //不能走的條件:越界、為牆、已訪問過 bool canmoveto(int x,int y,int d) //判斷方格[x,y]能否向方向d走一步 { switch(d) { case 0: //左 { if(y-1<1||maze[x][y-1]=='X'||used[x][y-1]==1) { return false; } else { break; } } case 1: //下 { if(x+1>12||maze[x+1][y]=='X'||used[x+1][y]==1) { return false; } else { break; } } case 2: //右 { if(y+1>12||maze[x][y+1]=='X'||used[x][y+1]==1) { return false; } else { break; } } case 3: //上 { if(x-1<1||maze[x-1][y]=='X'||used[x-1][y]==1) { return false; } else { break; } } } return true; } Node moveto(int x,int y,int d) //返回方格[x,y]向d走一步之後到達的格子node { Node next; switch(d) { case 0: //左 { next.x=x; next.y=y-1; break; } case 1: //下 { next.x=x+1; next.y=y; break; } case 2: //右 { next.x=x; next.y=y+1; break; } case 3: //上 { next.x=x-1; next.y=y; break; } } return next; }
【後記】
1.程式碼寫到現在,寫的第一個結構體佇列!作為一個當初自己瞎啃資料結構被難到哭泣的人,開森!