hdu1254 推箱子(兩種解法)

傳送門:https://vjudge.net/problem/HDU-1254node

題意:就是一個箱子的推箱子,問箱子最少走多少步到達目的地。ios

由於我c++實訓打算寫個推箱子游戲,看見有這題就過來打一下。。。。c++

這題兩種解法ide

第一種:就是普通的bfs,只是記錄狀態有四個值,分別是人的座標和箱子的座標,因爲n很小,因此vis[n][n][n][n]內存仍是能夠接受的。spa

 1 // Cease to struggle and you cease to live
 2 #include <iostream>
 3 #include <cmath>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <algorithm>
 7 #include <queue>
 8 #include <vector>
 9 #include <set>
10 #include <map>
11 #include <stack>
12 using namespace std; 13 typedef long long ll; 14 int mp[10][10]; 15 struct node{ 16     int px,py,bx,by,step; 17 }; 18 int dx[]={0,0,1,-1}; 19 int dy[]={1,-1,0,0}; 20 int vis[10][10][10][10]; 21 int main() { 22     int T;scanf("%d",&T); 23     for(int t=1;t<=T;++t){ 24         queue<node> Q; 25  node a; 26         a.step=0; 27         memset(vis,0x3f3f3f3f,sizeof(vis)); 28         int n,m;scanf("%d%d",&n,&m); 29         int psx,psy,bsx,bsy; 30         for(int i=1;i<=n;++i){ 31             for(int j=1;j<=m;++j){ 32                 scanf("%d",&mp[i][j]); 33                 if(mp[i][j]==4){ 34                     a.px=i;a.py=j; 35  } 36                 else if(mp[i][j]==2){ 37                     a.bx=i;a.by=j; 38  } 39  } 40  } 41         vis[a.bx][a.by][a.px][a.py]=0; 42  Q.push(a); 43         int ans=0x3f3f3f3f; 44         while(!Q.empty()){ 45             node u=Q.front(); 46  Q.pop(); 47             if(mp[u.bx][u.by]==3){ 48                 ans=min(ans,u.step); 49  } 50             for(int i=0;i<4;++i){ 51  node v; 52                 int xx=u.px+dx[i],yy=u.py+dy[i]; 53                 if(xx<1 || xx>n || yy<1 || yy>m) continue; 54                 if(mp[xx][yy]==1) continue; 55                 int bxx=u.bx,byy=u.by; 56                 int ok=0; 57                 if(xx==u.bx && yy==u.by){ 58                     ok=1; 59                     bxx=u.bx+dx[i],byy=u.by+dy[i]; 60                     if(bxx<1 || bxx>n || byy<1 || byy>m) continue; 61                     if(mp[bxx][byy]==1) continue; 62  } 63                 if(vis[bxx][byy][xx][yy]<=u.step+ok) continue; 64                 v.px=xx;v.py=yy;v.bx=bxx;v.by=byy;v.step=u.step+ok; 65  Q.push(v); 66                 vis[bxx][byy][xx][yy]=u.step+ok; 67  } 68  } 69         if(ans==0x3f3f3f3f) puts("-1"); 70         else printf("%d\n",ans); 71  } 72     return 0; 73 }
View Code

第二種:第二種解法是在網上學來的。由於箱子最少步,因此確定是對箱子bfs,可是箱子移動的前提是人可以到箱子的後面,因此在箱子的bfs中,箱子每次移動要對人跑一邊bfs,看看人能不能到達箱子移動的反方向(注意,人不能穿牆或者穿過箱子).net

 1 #include<bits/stdc++.h>
 2 using namespace std;  3 struct node{  4     int px,py,bx,by;  5     int step;  6 };  7 int dx[]={0,0,-1,1};  8 int dy[]={1,-1,0,0};  9 bool vis[10][10][5]; 10 bool fg[10][10]; 11 int mp[10][10]; 12 int n,m; 13 bool bfs(node fr,node to){ 14     memset(fg,0,sizeof(fg)); 15     queue<node> q; 16  q.push(fr); 17     while(!q.empty()){ 18         node u=q.front(); 19  q.pop(); 20         if(u.px==to.px && u.py==to.py) return true; 21         for(int i=0;i<4;++i){ 22             int xx=u.px+dx[i],yy=u.py+dy[i]; 23             if(xx<1 || xx>n || yy<1 || yy>m) continue; 24             if(fg[xx][yy]) continue; 25             if(mp[xx][yy]==1) continue; 26             if(xx==fr.bx && yy==fr.by) continue; 27             fg[xx][yy]=1; 28             node tem=u; 29             tem.px=xx;tem.py=yy; 30  q.push(tem); 31  } 32  } 33     return false; 34 } 35 int main(){ 36     int T;scanf("%d",&T); 37     for(int cas=1;cas<=T;++cas){ 38         scanf("%d%d",&n,&m); 39         memset(vis,0,sizeof(vis)); 40  node st; 41         st.step=0; 42         for(int i=1;i<=n;++i){ 43             for(int j=1;j<=m;++j){ 44                 scanf("%d",&mp[i][j]); 45                 if(mp[i][j]==4){ 46                     st.px=i;st.py=j; 47  } 48                 if(mp[i][j]==2){ 49                     st.bx=i;st.by=j; 50  } 51  } 52  } 53         queue<node> Q; 54  Q.push(st); 55         int ans=0x3f3f3f3f; 56         while(!Q.empty()){ 57             node u=Q.front(); 58  Q.pop(); 59             if(mp[u.bx][u.by]==3){ 60                 ans=min(ans,u.step); 61  } 62             //cerr<<u.bx<<' '<<u.by<<ans<<endl;
63             for(int i=0;i<4;++i){ 64                 int bxx=u.bx+dx[i],byy=u.by+dy[i]; 65                 int pxx=u.bx-dx[i],pyy=u.by-dy[i]; 66                 if(bxx<1 || bxx >n || byy<1 || byy >m) continue; 67                 if(vis[bxx][byy][i]) continue; 68                 if(pxx<1 || pxx>n || pyy<1 || pyy>m) continue; 69                 if(mp[bxx][byy]==1 || mp[pxx][pyy]==1) continue; 70                 node box=u,peo=u; 71                 peo.px=pxx;peo.py=pyy; 72                 if(bfs(u,peo)){ 73                     vis[bxx][byy][i]=1; 74                     box.bx=bxx;box.by=byy; 75                     box.px=u.bx;box.py=u.by; 76                     box.step=u.step+1; 77  Q.push(box); 78  } 79  } 80  } 81         if(ans==0x3f3f3f3f) puts("-1"); 82         else printf("%d\n",ans); 83  } 84     return 0; 85 }
View Code

如今就六月份了,考前一個月用來複習了,也就是說打完這題,以及明天的訓練賽,我就完全不碰鍵盤一個月了。想一想仍是有點不捨得的。那麼這題就當作是個人封建盤一個月的收山之做吧。哈哈哈哈。code

相關文章
相關標籤/搜索