SDUT 2410 Mine Number DFS+回溯 (扫雷)
2016-03-22 16:16
615 查看
点击打开链接
DFS,深度优先搜索。
大体的思路方向是:
从0,0开始往后判断,每个点是否放雷,依据就是周围的数字(上下左右)是否有0的情况,有0就不放雷。
放雷后就要将五个方向的数字减1,然后继续往后判断。
这是主要的判断,但是显然需要大的前提来 剪掉大半棵树。
→首先将第一行枚举,然后每一行根据上一行状态来做:
如果上一行同位置数字为0,则该点不放雷。
如果上一行同位置数字为1,则该点必须放雷,此时判断四周是否有0的情况,没有则放雷,有则回溯。
如果上一行同位置数字不为0或者1,则回溯。
判断到最后一行,需要将最后一行数组判断,是否全为0,是则输出结果,不是则回溯。
DFS,深度优先搜索。
大体的思路方向是:
从0,0开始往后判断,每个点是否放雷,依据就是周围的数字(上下左右)是否有0的情况,有0就不放雷。
放雷后就要将五个方向的数字减1,然后继续往后判断。
这是主要的判断,但是显然需要大的前提来 剪掉大半棵树。
→首先将第一行枚举,然后每一行根据上一行状态来做:
如果上一行同位置数字为0,则该点不放雷。
如果上一行同位置数字为1,则该点必须放雷,此时判断四周是否有0的情况,没有则放雷,有则回溯。
如果上一行同位置数字不为0或者1,则回溯。
判断到最后一行,需要将最后一行数组判断,是否全为0,是则输出结果,不是则回溯。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define LL long long #define mod 1000000007 using namespace std; #define N 1001 char s[100][100]; int a[100][100]; char c[100][100]; char Map[100][100]; int n,m; int dx[]= {-1,1,0,0,0}; int dy[]= {0,0,0,-1,1}; ///判断边界 int judge(int x,int y) { if(x<0||y<0||x>=n||y>=m) return 0; return 1; } ///判断周围的5处地方 是否存在 小于等于0 的情况 int solve(int x,int y) { for(int i=0; i<5; i++) { int fx=dx[i]+x; int fy=dy[i]+y; if(judge(fx,fy)&&a[fx][fy]<=0) return 0; } return 1; } ///对周围的5处的 *的个数 进行操作 +1 或 -1 void change(int x,int y,int c) { for(int i=0; i<5; i++) { int fx=dx[i]+x; int fy=dy[i]+y; if(judge(fx,fy)) a[fx][fy]=a[fx][fy]+c; } } int flag=0; int DFS(int x,int y) { if(flag) ///找到了满足条件的 return 0; if(x==n) { int f=0; for(int i=0; i<m; i++) ///判断最后一行的a[][] 是否全为0 if(a[n-1][i]) { f=1; break; } if(!f) { for(int i=0; i<n; i++) { for(int j=0; j<m; j++) printf("%c",Map[i][j]); printf("\n"); } flag=1; } return 0; } if(y==m) { DFS(x+1,0); ///return 0; } else if(x==0) { if(solve(x,y)) ///周围有*的个数为0 的情况所以 此处为 '.' { Map[x][y]='*'; change(x,y,-1); DFS(x,y+1); change(x,y,+1); } ///1周围有*的个数为0 的情况所以 此处为 '.' 或者2 是回溯后的情况 Map[x][y]='.'; DFS(x,y+1); } else { if(a[x-1][y]==0) ///上一层为0 下一层一定为 ‘.’ { Map[x][y]='.'; DFS(x,y+1); } else if(a[x-1][y]==1) ///上一层为1 该层一定为 ‘*’; { if(solve(x,y)) { Map[x][y]='*'; change(x,y,-1); DFS(x,y+1); change(x,y,1); } } } } int main() { int T; while(~scanf("%d",&T)) { for(int cas=1; cas<=T; cas++) { /// memset(vis,0,sizeof(vis)); scanf("%d%d",&n,&m); for(int i=0; i<n; i++) { scanf("%s",s[i]); for(int j=0; j<m; j++) a[i][j]=s[i][j]-'0'; } flag=0; printf("Case %d:\n",cas); DFS(0,0); } } return 0; }
相关文章推荐
- hdu1711 Number Sequence 求模式串在主串中的位置
- nohup 命令
- 数据结构(看了之后还不懂我退出IT界)
- 第一篇:数据仓库概述
- node.js 调试
- NSInteger和BOOL的底层类型
- PHP获取多个checkbox的值
- HOSt ip is not allowed to connect to this MySql server
- 开关控件 UISwitch
- UVALive 7037 (最大密度子图 网络流)
- Building Android Kernel for the Nexus 5 — AOSP(6.0.1)
- 头文件中ifndef define...endif
- 淘宝notify-消息中间件(2)
- C/C++ 如何调用Lua中的数据
- HDU--5280(dp或枚举)
- java.lang.UnsupportedClassVersionError
- 【Linux】理解setuid()、setgid()和sticky位
- Java多线程系列--“JUC原子类”01之 框架
- jqGrid简单介绍
- [ios]使用代码进行故事板创建的视图的跳转 ?