hdu 3713 Double Maze(四维的BFS)
2013-10-16 18:58
239 查看
记得以前刚学广搜的时候,做了很多迷宫的问题。后来做了一道数字转换的题目,按照一定的规则改变数字,看最快多少步能转换成目标数字。那道题我写了个广搜A掉了。当时我就在想,我做过二维和三维的迷宫问题,数字转换这道题可以看成是一维的迷宫,那应该还有四维和五维的迷宫,写法上应该差不多,不过多了一个方向,多了一个维度。
这道题两个maze分开看的话每个点都可以到达多次,但是如果两个maze放在一块儿,将他们两个的状态作为一个状态来记录,那么这个状态就只能到达一次。比如说对于第一个maze中的1,3这个点和第二个maze中的2,4这个点,这两个点都可以到达很多次,但是第一个maze在1,3,同时第二个maze在2,4这种状态却只允许出现一次。这样这道题就变成了一个有6^4种状态的迷宫,看最快需要多久才能到达终点状态,并且输出字典序最小的。
将两个出发点放在一块儿当作起始状态,两个终点放在一块儿当作终点状态,做一次bfs,在每一个状态记录它的前驱状态。将四个方向按照字典序排序,这样搜索到的第一个终点就是字典序最小的方案,然后递归输出方案。
没有注意起点和终点可以是同一点,wa了许久。。。。
这道题两个maze分开看的话每个点都可以到达多次,但是如果两个maze放在一块儿,将他们两个的状态作为一个状态来记录,那么这个状态就只能到达一次。比如说对于第一个maze中的1,3这个点和第二个maze中的2,4这个点,这两个点都可以到达很多次,但是第一个maze在1,3,同时第二个maze在2,4这种状态却只允许出现一次。这样这道题就变成了一个有6^4种状态的迷宫,看最快需要多久才能到达终点状态,并且输出字典序最小的。
将两个出发点放在一块儿当作起始状态,两个终点放在一块儿当作终点状态,做一次bfs,在每一个状态记录它的前驱状态。将四个方向按照字典序排序,这样搜索到的第一个终点就是字典序最小的方案,然后递归输出方案。
没有注意起点和终点可以是同一点,wa了许久。。。。
#include<stdio.h> #include<string.h> #include<queue> using namespace std; #define N 8 int mark ; int a ,b ; int ans[10005]; int dir[4][4]= {{1,0,1,0},{0,-1,0,-1},{0,1,0,1},{-1,0,-1,0}}; int flag[4]= {2,1,4,8}; char s[4]= {'D','L','R','U'}; struct node { int x,y; int xx,yy; int x1,y1,x2,y2; } sa,sb,ea,eb,vis ; int judge(node c) { if(mark[c.x][c.y][c.xx][c.yy]==1) return 0; if((a[c.x][c.y]&16)==0) return 0; if((b[c.xx][c.yy]&16)==0) return 0; return 1; } int bfs() { queue<node>q; node cur,next; cur.x=sa.x; cur.y=sa.y; cur.xx=sb.x; cur.yy=sb.y; if(cur.x==ea.x&&cur.y==ea.y&&cur.xx==eb.x&&cur.yy==eb.y) return 0; mark[cur.x][cur.y][cur.xx][cur.yy]=1; q.push(cur); while(!q.empty()) { cur=q.front(); q.pop(); for(int i=0; i<4; i++) { if((a[cur.x][cur.y]&flag[i])==0) { next.x=cur.x+dir[i][0]; next.y=cur.y+dir[i][1]; } else { next.x=cur.x; next.y=cur.y; } if((b[cur.xx][cur.yy]&flag[i])==0) { next.xx=cur.xx+dir[i][2]; next.yy=cur.yy+dir[i][3]; } else { next.xx=cur.xx; next.yy=cur.yy; } if(judge(next)) { vis[next.x][next.y][next.xx][next.yy].x1=cur.x; vis[next.x][next.y][next.xx][next.yy].y1=cur.y; vis[next.x][next.y][next.xx][next.yy].x2=cur.xx; vis[next.x][next.y][next.xx][next.yy].y2=cur.yy; mark[next.x][next.y][next.xx][next.yy]=1; // printf("%d %d %d %d %c %d %d %d %d\n",cur.x,cur.y,cur.xx,cur.yy,s[i],next.x,next.y,next.xx,next.yy); if(next.x==ea.x&&next.y==ea.y&&next.xx==eb.x&&next.yy==eb.y) return 0; q.push(next); } } } return 1; } void print(int x,int y,int xx,int yy) { int tx,ty,txx,tyy; tx=x; ty=y; txx=xx; tyy=yy; if(x==sa.x&&y==sa.y&&xx==sb.x&&yy==sb.y) return ; x=vis[tx][ty][txx][tyy].x1; y=vis[tx][ty][txx][tyy].y1; xx=vis[tx][ty][txx][tyy].x2; yy=vis[tx][ty][txx][tyy].y2; print(x,y,xx,yy); for(int i=0; i<4; i++) { if((tx+dir[i][0]==x&&ty+dir[i][1]==y)||(txx+dir[i][2]==xx&&tyy+dir[i][3]==yy)) { if(i==1) i=2; else if(i==2) i=1; else if(i==3) i=0; else if(i==0) i=3; printf("%c",s[i]); return ; } } return ; } int main() { int T; scanf("%d",&T); int cnt=0; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); while(cnt<T) { if(cnt%2==0) { for(int i=1; i<=6; i++) { for(int j=1; j<=6; j++) { scanf("%d",&a[i][j]); if(a[i][j]&32) { sa.x=i; sa.y=j; } if(a[i][j]&64) { ea.x=i; ea.y=j; } } } } else { for(int i=1; i<=6; i++) { for(int j=1; j<=6; j++) { scanf("%d",&b[i][j]); if(b[i][j]&32) { sb.x=i; sb.y=j; } if(b[i][j]&64) { eb.x=i; eb.y=j; } } } } cnt++; if(cnt<2) continue; memset(vis,-1,sizeof(vis)); memset(mark,0,sizeof(mark)); if(bfs()) { printf("-1\n"); continue; } print(ea.x,ea.y,eb.x,eb.y); printf("\n"); } return 0; }
相关文章推荐
- HDU-3713:Double Maze(双重BFS)
- uvalive 5008 hdu 3717 double maze 四维bfs(好题)
- HDU-3713---Double Maze (bfs) 详细解释
- HDU 3713 Double Maze
- HDU 3713 Double Maze
- hdu1195 Open the Lock 广搜BFS 四维数组标记
- hdoj 3713 Double Maze (四维BFS + 打印路径)
- HDU 3713 Double Maze
- HDU 3713 Double Maze
- HDU 3713 Double Maze(DFS)
- hdu - 2216 Game III && xtu 1187 Double Maze (两个点的普通bfs)
- HDU 5025 Saving Tang Monk --BFS
- hdu 1242 Rescue(bfs)
- hdu 1429 状压bfs
- HDU 1195 Open the Lock (双向BFS)
- HDU 1372 Knight Moves(BFS)
- hdu 1242 bfs
- ID(dfs+bfs)-hdu-4127-Flood-it!
- POJ 2225 && HDU 1240 Asteroids!(bfs)
- HDU 1043 Eight(BFS)