uva10384 The Wall Pusher 推门游戏
来源:互联网 发布:科比布莱恩特生涯数据 编辑:程序博客网 时间:2024/05/29 14:27
问题
从S出发,每次往东南西北四个方向前进。 如果前方有墙壁,游戏者可以往前推移一格。 如果有连续两堵墙(包含)以上的墙,或者是游戏区域边界上的墙 则推不动。
求最少步数走出迷宫 4行6列,多解时任意输出一格移动序列即可
思路
迷宫怎么存储
用三元组表示一堵墙
数组wallX[y][x1][x2] 表示第y=y时 从x1与x2之间有一堵墙
数组wallY[x][y1][y2] 表示第x=x时 从y1与y2之间有一堵墙
数组wallX wallY 就能刻画迷宫的形状起点S(x, y) 如何判断应走出迷宫
行y[1, 4] 列x[1,6]; 增加虚拟行y=0、5 虚拟列x=0、7
如果能走到 (0, *)|(7, *)|(*,0)|(*,5) 其中任意一个位置 即走出迷宫- 如何保证步数最少
解决迷宫问题 一般都用递归;
用深度优先DFS获取的第一条路径不一定是最短的;
用广度优先BFS,第一条路径肯定是最短的 但需要维护一个队列,存储每走一步后的迷宫状态,很占空间;
如果用迭代加深搜素算法IDA*则能有效解决上述问题,即限定BFS的深度,并依次递增知道找到问题的解
for(depth=1; ;depth++) DFS(S0); // 限制递归深度最大为depth if find soulation: break;
测试案例 & 结果
输入:x 1 6 7x 2 0 1x 2 2 3x 2 4 5x 2 6 7x 3 0 1x 3 1 2x 3 2 3x 3 4 5x 3 5 6x 3 6 7x 4 1 2x 4 3 4x 4 5 6y 1 0 1y 1 1 2y 1 3 4y 1 4 5y 2 0 1y 2 2 3y 2 3 4y 2 4 5y 3 0 1y 3 1 2y 3 2 3y 3 4 5y 4 0 1y 4 1 2y 4 2 3y 4 4 5y 5 0 1y 5 2 3y 5 3 4y 5 4 5y 6 0 1y 6 3 4y 6 4 50 0 0 0打印图像:--------@@_@_@_@_@_@_@@@@@_@@@_@_@@@@|@@@|@@_|_@_|_@@|@@@|_|_|@@@|_|_|@@@@_|_@_|_@_|_@@@@@@@@@@@@@@@@@@@--------行走路径:(2 3)(2 2)(3 2)(3 3)(4 3)(4 4)(5 4)(6 4)(6 3)(6 2)(5 2)(5 1)(4 1)(3 1)(2 1)(1 1)(0 1)
代码
#include <stdio.h>#include <stdlib.h>#define MaxDepth 100//当前允许递归的最大深度int curMaxDepth;//保存行走路径int ansX[MaxDepth], ansY[MaxDepth];//保存迷宫墙的信息int wallX[6][8][8], wallY[8][6][6];// 行走方向 东 南 西 北int dirX[]={1, 0 , -1, 0}, dirY[]={ 0, 1, 0, -1};// x、y的最大值int maxX=7, maxY=5;// 起点int beginX=2, beginY=3;// 打印图像void showWall(){ int i,j; printf("--------\n"); for(j=0; j<6; j++) { for(i=0;i<8;i++) { if( wallX[j][i][i+1]==1 && wallY[i][j][j+1]==1 ) printf("_|"); else if ( wallX[j][i][i+1]==1 && wallY[i][j][j+1]==0 ) printf("@|"); else if ( wallX[j][i][i+1]==0 && wallY[i][j][j+1]==1 ) printf("_@"); else if ( wallX[j][i][i+1]==0 && wallY[i][j][j+1]==0 ) printf("@@"); } printf("\n"); } printf("--------\n");}// 找第step步的解int find(int step){ int x, y, nextX, nextY, i, j, k, wallMoved; x = ansX[step-1]; y = ansY[step-1]; // no solution; if( step > curMaxDepth ) return 0; // 四个方向 进行尝试 for(i=0; i<4; i++) { nextX = x+dirX[i]; nextY = y+dirY[i]; wallMoved = 0; // 有墙 && (墙后还是墙||是边界墙) 无解 if( wallX[y][x][nextX] && ( wallX[y][nextX][nextX+dirX[i]] || nextX==0 || nextX==7) ) continue; if ( wallY[x][y][nextY] && ( wallY[x][nextY][nextY+dirY[i]] || nextY==0 || nextY==5) ) continue; // 左|右 移动墙壁 if( dirX[i] != 0 && wallX[y][x][nextX]) { wallMoved = 1; wallX[y][x][nextX] = 0; wallX[y][nextX][x] = 0; wallX[y][nextX][nextX+dirX[i]] = 1; wallX[y][nextX+dirX[i]][nextX] = 1; } // 上|下 移动墙壁 if( dirY[i] != 0 && wallY[x][y][nextY]) { wallMoved = 1; wallY[x][y][nextY] = 0; wallY[x][nextY][y] = 0; wallY[x][nextY][nextY+dirY[i]] = 1; wallY[x][nextY+dirY[i]][nextY] = 1; } //保存 移动后的坐标 ansX[step]=nextX; ansY[step]=nextY; // find solution if ( nextX==0 || nextX==7 || nextY==0 || nextY==5 ) return 1; // 继续递归求解 if ( find(step+1) ) return 1; // 恢复墙壁 if( wallMoved ==1 ) { if ( dirX[i] != 0 ) { wallX[y][x][nextX] = 1; wallX[y][nextX][x] = 1; wallX[y][nextX][nextX+dirX[i]] = 0; wallX[y][nextX+dirX[i]][nextX] = 0; } if(dirY[i] != 0 ) { wallY[x][y][nextY] = 1; wallY[x][nextY][y] = 1; wallY[x][nextY][nextY+dirY[i]] = 0; wallY[x][nextY+dirY[i]][nextY] = 0; } } } return 0;}int alg10384(){ char flag[8]; int i, j, a, b, c; while(scanf("%s %d %d %d", flag, &a, &b, &c )==4) { if (a==0&&b==0&&c==0) break; if(flag[0]=='x'||flag[0]=='X') { wallX[a][b][c]=1; wallX[a][c][b]=1; } if(flag[0]=='y'||flag[0]=='Y') { wallY[a][b][c]=1; wallY[a][c][b]=1; } } showWall(); ansX[0]=beginX; ansY[0]=beginY; for(curMaxDepth=1; curMaxDepth <= MaxDepth; curMaxDepth++) { if( find(1) ) break; } for(i=0; i<=curMaxDepth; i++) { printf("%d %d\n", ansX[i], ansY[i]); } return 0;}
阅读全文
0 0
- uva10384 The Wall Pusher 推门游戏
- UVa 10384:The Wall Pusher(IDA*)
- UVA 10384(p219)----The Wall Pusher
- UVa11040 - Add bricks in the wall (规律递推)
- UVA-11040-Add Bricks in the wall(规律、递推)
- Pink Floyd -- The Wall
- hdu2124 Repair the Wall
- hdu1543 Paint the Wall
- hdu1543 Paint the Wall
- Repair the Wall+贪心
- A. The Wall
- Paint The Wall hdu4391
- codeforces The Wall - 题解
- Repair the Wall
- [cf398B]Painting The Wall
- 10384 - The Wall Pushers
- Fixing the Great Wall
- 2124:Repair the Wall
- 百度地图移动版API终于发布了(Android)
- 数组方法实现(一)————数组方法join()
- JPA之使用JPQL语句操作数据库
- 原 Spring + SpringMVC + Mybatis 整合,实现 CRUD (增删改查)
- 《机器学习实战》总结:ID3决策树
- uva10384 The Wall Pusher 推门游戏
- Mongo 聚合框架-Aggregate(二)
- XML的四种生成方式
- php表示一年,一个星期等时间,很好用,方便
- servlet -1
- 链表习题
- ubuntu 卸载 /安装google-chrome
- Oracle PL/SQL常用命令
- svg绘制简单图形