1254 推箱子(標記狀態,思路)
阿新 • • 發佈:2019-02-15
推箱子是一個很經典的遊戲.今天我們來玩一個簡單版本.在一個M*N的房間裡有一個箱子和一個搬運工,搬運工的工作就是把箱子推到指定的位置,注意,搬運工只能推箱子而不能拉箱子,因此如果箱子被推到一個角上(如圖2)那麼箱子就不能再被移動了,如果箱子被推到一面牆上,那麼箱子只能沿著牆移動.
現在給定房間的結構,箱子的位置,搬運工的位置和箱子要被推去的位置,請你計算出搬運工至少要推動箱子多少格.
Input輸入資料的第一行是一個整數T(1<=T<=20),代表測試資料的數量.然後是T組測試資料,每組測試資料的第一行是兩個正整數M,N(2<=M,N<=7),代表房間的大小,然後是一個M行N列的矩陣,代表房間的佈局,其中0代表空的地板,1代表牆,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬運工的起始位置.
Output對於每組測試資料,輸出搬運工最少需要推動箱子多少格才能幫箱子推到指定位置,如果不能推到指定位置則輸出-1.
Sample Input Sample Output
現在給定房間的結構,箱子的位置,搬運工的位置和箱子要被推去的位置,請你計算出搬運工至少要推動箱子多少格.
Input輸入資料的第一行是一個整數T(1<=T<=20),代表測試資料的數量.然後是T組測試資料,每組測試資料的第一行是兩個正整數M,N(2<=M,N<=7),代表房間的大小,然後是一個M行N列的矩陣,代表房間的佈局,其中0代表空的地板,1代表牆,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬運工的起始位置.
Output對於每組測試資料,輸出搬運工最少需要推動箱子多少格才能幫箱子推到指定位置,如果不能推到指定位置則輸出-1.
Sample Input
1 5 5 0 3 0 0 0 1 0 1 4 0 0 0 1 0 0 1 0 2 0 0 0 0 0 0 0
4
題意: 搬運工推箱子,推到指定位置所用的最小步數;
思路:箱子到指定位置,要是不用人推直接 bfs 往四周走,找最短路徑就行了,但是箱子必須有人推,箱子可以往四個方向走,箱子要想走的話,如箱子要想往右走,箱子左右的位子為0,且搬運工能到達箱子左邊的方格; 這時候要怎麼標記 箱子的狀態呢,要是和一般的普通標記是一定不行了,箱子可能往上下左右四個方向走(被推),所以箱子有四種狀態
寫這樣的搜尋題:一定要想法標記狀態,找準它有幾種狀態 還就可能用優先佇列寫,還有就是,用個二維陣列記錄走到這個點時的最小(步數或拐彎數等等),減少搜尋時間,大大提高搜尋效率;
程式碼:
#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; #define Max 8 int end_x,end_y; struct node { int step; int x,y; int star_x,star_y; }; int a[4][2] = {0,-1,1,0,0,1,-1,0}; int n,m; int book[Max][Max][4]; // 標記狀態; 這個箱子可以往四個方向走,也可以說成被四個方向的人推; int str[Max][Max]; //所以有四個狀態; int vis[Max][Max]; int check(int x,int y) { if(x>=0&&x<n&&y>=0&&y<m) return 1; else return 0; } int dfs(int x,int y,int tx,int ty,int kx,int ky) // x,y 當前搬運工的位置,tx,ty為要到達的座標; { // kx,ky 為箱子的座標; if(x==tx&&y==ty) return 1; vis[y][x] = 1; for(int i = 0;i<4;i++) { int dx = x + a[i][0]; int dy = y + a[i][1]; if(dx==kx&&dy==ky) continue; if(check(dx,dy)&&!vis[dy][dx]&&str[dy][dx]!=1) { if(dfs(dx,dy,tx,ty,kx,ky)) return 1; } } return 0; } int bfs(int x,int y,int star_x,int star_y) { queue<node> q; node tt; tt.x = x; tt.y = y; tt.star_x = star_x; tt.star_y = star_y; tt.step = 0; q.push(tt); while(!q.empty()) { tt = q.front(); q.pop(); for(int i = 0;i < 4;i ++) { int x = tt.x + a[i][0]; int y = tt.y + a[i][1]; int j = (i+2)%4; int tx = tt.x + a[j][0]; int ty = tt.y + a[j][1]; if(check(x,y)&&check(tx,ty)) if(str[y][x] != 1&&str[ty][tx] != 1&&!book[tt.y][tt.x][i]) { memset(vis,0,sizeof(vis)); if(dfs(tt.star_x,tt.star_y,tx,ty,tt.x,tt.y)) { book[tt.y][tt.x][i] = 1; node kk; kk.x = x; kk.y = y; kk.star_x = tt.x; kk.star_y = tt.y; kk.step = tt.step + 1; if(str[y][x]==3) return kk.step; q.push(kk); } } } } return -1; } int main() { int i,j,t; scanf("%d",&t); int star_x,star_y,x,y; while(t--) { scanf("%d%d",&m,&n); for(i=0;i<m;i++) for(j = 0;j<n;j++) { scanf("%d",&str[i][j]); if(str[i][j]==3) { end_x = j; end_y = i; } else if(str[i][j]==2) { x = j; y = i; } else if(str[i][j]==4) { star_x = j; star_y = i; } } memset(book,0,sizeof(book)); printf("%d\n",bfs(x,y,star_x,star_y)); } return 0; }