csu - 1566: The Maze Makers (bfs)
2015-05-31 21:06
309 查看
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1566
题意还是蛮难懂的,至少对于我来说,需要认真读题。
输入矩阵的每一个数字换成2进制后,顺时针围一圈,用1表示墙,0表示空,这样就可以表示出一个迷宫,现在就是判断这个迷宫属于4种类型中哪种类型。
参考了 大神博客。构图很难,并且想法跟以往的题都不一样。是一个好题。
题意还是蛮难懂的,至少对于我来说,需要认真读题。
输入矩阵的每一个数字换成2进制后,顺时针围一圈,用1表示墙,0表示空,这样就可以表示出一个迷宫,现在就是判断这个迷宫属于4种类型中哪种类型。
参考了 大神博客。构图很难,并且想法跟以往的题都不一样。是一个好题。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <string> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #pragma comment(linker, "/STACK:102400000,102400000") #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long #define inf 0x7f7f7f7f #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("a.txt", "r", stdin) #define Write() freopen("b.txt", "w", stdout); #define maxn 1000000000 #define N 2510 #define mod 1000000000 using namespace std; int n,m; int num[55][55],vis[55][55]; int dir[4][3]={1,0,2,-1,0,8,0,1,4,0,-1,1}; //这里必须要对应 是为了防止往回走 struct point { int a,b; }; int main() { //freopen("a.txt","r",stdin); char s[55]; int x,y,nx,ny; while(~scanf("%d%d",&n,&m)) { if(!n&&!m) break; for(int i=1;i<=n;i++) { scanf("%s",s+1); for(int j=1;j<=m;j++) { if(s[j]>='0'&&s[j]<='9') num[i][j]=s[j]-'0'; else num[i][j]=s[j]-'A'+10; num[i][j]=~num[i][j]; //读入之后 按位取反 ,能走的变成1 不能走的变成0 } } x=0; //找出 起点和终点 for(int i=1;i<=n;i++) //第一列或者第m列 看左右边界 { if(num[i][1]&1) //代表表示 num[i][1]的四位2进制数中最后一位是1 代表有缺口 { if(!x) x=i,y=1; else nx=i,ny=1; } if(num[i][m]&4) { if(!x) x=i,y=m; else nx=i,ny=m; } } for(int i=1;i<=m;i++) //同上,看上下边界 { if(num[1][i]&8) { if(!x) x=1,y=i; else nx=1,ny=i; } if(num [i]&2) { if(!x) x=n,y=i; else nx=n,ny=i; } } // printf("%d %d %d %d\n",x,y,nx,ny); memset(vis,0,sizeof(vis)); int mul=0; queue<point>que; point now,next; now.a=x,now.b=y; vis[now.a][now.b]=16; que.push(now); while(!que.empty()) //扩展所有能到达的点 { next=que.front();que.pop(); for(int i=0;i<4;i++) { if(vis[next.a][next.b]==dir[i][2]) continue; //已经访问过,防止往回走, if(num[next.a][next.b]&dir[i][2]) //该方向能访问 { now.a=next.a+dir[i][0]; now.b=next.b+dir[i][1]; if(now.a>=1&&now.a<=n&&now.b>=1&&now.b<=m) { if(vis[now.a][now.b]) mul=1; //多次到达同一个点 else { if(dir[i][2]==4) vis[now.a][now.b]=1; //赋值相反方向的值给vis,防止往回走,跟上面的判断对应 else if(dir[i][2]==1) vis[now.a][now.b]=4; else if(dir[i][2]==8) vis[now.a][now.b]=2; else if(dir[i][2]==2) vis[now.a][now.b]=8; que.push(now); } } } } } if(vis[nx][ny]) //能到出口 { bool flag=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) if(!vis[i][j]) { //printf("%d %d\n",i,j); flag=1; break; } if(flag) break; } if(flag) printf("UNREACHABLE CELL\n"); //有点不能到达 else { if(mul) printf("MULTIPLE PATHS\n"); //多次到达 else printf("MAZE OK\n"); //只有一条路径 } } else printf("NO SOLUTION\n"); //没有路径 } return 0; }
相关文章推荐
- MySQL 命令汇总
- 消息队列处理方式
- iOS7/8 UIButton高亮状态延迟有关问题全解
- ANSIC和Unicode之间的转换
- COJ 0501 取数游戏(TPM)
- 一.计算机网络概述
- 任务调度系统
- Java 正则表达式
- 网上找到的JNI用法
- fatal error LNK1104: cannot open file "Debug/构造函数.exe"
- 2015百度之星初赛(二) 连接的管道 1002
- 数据库数据处理故事多
- HDFS HA切换后missing block问题分析
- 找出数组中任何相邻子向量的最大和
- Java 正则表达式详解
- 在Winform中实现拖放的功能
- 隔行变色的表格
- 阿里巴巴Dubbo实现的源码分析
- Windows Phone 8.1中AppBarToggleButton的绑定问题
- hdu 5256 最少修改多少个数 能使原数列严格递增 (LIS)