ZOJ 1675 Push!!(BFS)

来源:互联网 发布:多益网络招聘坑人 编辑:程序博客网 时间:2024/06/15 14:34

用了两个BFS

第一个BFS是搜箱子的位置,第二个BFS是判断人是否能够到达箱子的下一个位置的相反位置,只有在相反的位置他才能把箱子推到指定的位置

判重的话要用个三维数组vis[i][j][k] k表示从哪个方向过来

#include <iostream>#include <memory.h>#include <cstdio>#include <queue>using namespace std;struct state{int pCuri,pCurj,cCuri,cCurj,times;state(int pcci=0,int pccj=0,int ccci=0,int cccj=0,int tt=0):pCuri(pcci),pCurj(pccj),cCuri(ccci),cCurj(cccj),times(tt){}};int di[]={-1,1,0,0},dj[]={0,0,-1,1},rdi[]={1,-1,0,0},rdj[]={0,0,1,-1};int grid[8][8],ti,tj,n,m;bool vis1[8][8][4],vis2[8][8];bool bfs2(int si,int sj,int ti,int tj){//check if the warehouseman can reach the specified positionmemset(vis2,0,sizeof(vis2));queue<int>q;vis2[si][sj]=1;q.push(si*m+sj);while (q.size()){int curp=q.front();q.pop();int ci=curp/m,cj=curp%m;if(ci==ti&&cj==tj){return true;}for (int i=0;i<4;++i){int ni=ci+di[i],nj=cj+dj[i];if(ni>=0&&ni<n&&nj>=0&&nj<m&&!vis2[ni][nj]&&!grid[ni][nj]){vis2[ni][nj]=1;q.push(ni*m+nj);}}}return false;}int bfs1(state st){memset(vis1,0,sizeof(vis1));queue<state>q;q.push(st);while (q.size()){state t=q.front();q.pop();if(t.cCuri==ti&&t.cCurj==tj){return t.times;}for (int i=0;i<4;++i){int ni=t.cCuri+di[i],nj=t.cCurj+dj[i];if(ni>=0&&ni<n&&nj>=0&&nj<m&&!vis1[ni][nj][i]&&!grid[ni][nj]){int pni=t.cCuri+rdi[i],pnj=t.cCurj+rdj[i];grid[t.cCuri][t.cCurj]=1;if(pni>=0&&pni<n&&pnj>=0&&pnj<m&&!grid[ni][nj]&&bfs2(t.pCuri,t.pCurj,pni,pnj)){vis1[ni][nj][i]=1;q.push(state(t.cCuri,t.cCurj,ni,nj,t.times+1));}grid[t.cCuri][t.cCurj]=0;}}}return -1;}int main(){while (scanf("%d%d",&m,&n)){if(!n&&!m)break;int psi=0,psj=0,csi=0,csj=0;for (int i=0;i<n;++i){for (int j=0;j<m;++j){scanf("%d",&grid[i][j]);if(grid[i][j]==2){csi=i,csj=j;grid[i][j]=0;}else if(grid[i][j]==3){ti=i,tj=j;grid[i][j]=0;}else if(grid[i][j]==4){psi=i,psj=j;grid[i][j]=0;}}}state sta(psi,psj,csi,csj,0);printf("%d\n",bfs1(sta));}return 0;}



原创粉丝点击