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

相关文章
相关标签/搜索