SDUT 2410 Mine Number DFS+回溯 (扫雷)

来源:互联网 发布:华为办公网络 编辑:程序博客网 时间:2024/06/14 06:05

点击打开链接

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 1000000007using namespace std;#define N 1001char 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 或 -1void 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;}


0 0