FZU Problem 1920 Left Mouse Button[dfs ||bfs,扫雷游戏]

来源:互联网 发布:怎么做淘宝客服在家兼职 编辑:程序博客网 时间:2024/05/03 21:00

题目链接:http://acm.fzu.edu.cn/problem.php?pid=1920

题目的意思,就是典型的扫雷游戏。。给你所有格子的情况。。问你最少多少步可以结束游戏。。。当然,我们知道炸弹在哪。。。

表示扫雷游戏玩的少。。。观察能力羸弱。。平常虽然也有玩过这个游戏。。但是,点到空白就出现所有周围的一圈也被暴露。。。

看图:

ACM绝对是考验一个人的综合能力。。。这一点是毋庸置疑的。。come on。。

然后,我们需要步数最少。。

那么,那么我们的策略就是最先把空白的点开。。然后依次点开就好了。。

bfs Code:

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>#include <queue>using namespace std;const int N = 15;const int dx[] = {0, 0, 1, 1, 1, -1, -1, -1};// up down downconst int dy[] = {1, -1, -1, 0, 1, -1, 0, 1};char map[N][N];int n;struct Node{    int x, y;    Node() {}    Node(int a, int b){        x = a;        y = b;    }};void bfs(int x, int y){    queue<Node> q;    q.push(Node(x, y));    while(!q.empty()){        Node tmp = q.front(), tmp1;        if(map[tmp.x][tmp.y] == '0')        for(int i = 0 ; i < 8; i ++){            tmp1.x = tmp.x + dx[i]; tmp1.y = tmp.y + dy[i];            if(tmp1.x < 1 || tmp1.x > n || tmp1.y < 1 || tmp1.y > n || map[tmp1.x][tmp1.y] == '@') continue;            q.push(tmp1);        }        map[tmp.x][tmp.y] = '@';        q.pop();    }    return ;}int main(){    int T, k = 1;    cin >> T;    while(T --){        cin >> n;        getchar();        for(int i = 1; i <= n; i ++){            for(int j  = 1; j <= n; j ++){                scanf("%c", &map[i][j]);            }            getchar();        }        int ans = 0;        for(int i = 1; i <= n; i ++){            for(int j = 1; j <= n; j ++){                if(map[i][j] == '0'){                    bfs(i, j);                    ans ++;                }            }        }        for(int i = 1; i <= n; i ++){            for(int j = 1; j <= n; j ++){                if(map[i][j] != '@'){                    ans ++;                }            }        }        cout << "Case " << k ++ << ": ";        cout << ans << endl;    }    return 0;}


bfs对于我来说还是比较好写的。。


dfs Code:

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define CLR(arr, val) memset(arr, val, sizeof(arr))const int N = 15;const int dx[] = {0, 0, 1, 1, 1, -1, -1, -1};const int dy[] = {1, -1, -1, 0, 1, -1, 0, 1};char map[N][N];int n;void dfs(int x, int y){    if(map[x][y] == '0'){// 前提.        map[x][y] = '@';// you must put it on there. because mybe  1->2->1... you understand for a little..        for(int i = 0; i < 8; i ++){            int gox = x + dx[i], goy = y + dy[i];            if(gox < 1 || gox > n || goy < 1 || goy > n) continue;            dfs(gox, goy);        }    }    map[x][y] = '@';}int main(){//    freopen("1.txt", "r", stdin);    int T, k = 1;    scanf("%d", &T);    while(T --){        scanf("%d", &n);        getchar();        for(int i = 1; i <= n; i ++){            for(int j  = 1; j <= n; j ++){                scanf("%c", &map[i][j]);            }            getchar();        }        int ans = 0;        for(int i = 1; i <= n; i ++){            for(int j = 1; j <= n; j ++){                if(map[i][j] == '0'){                    dfs(i, j);                    ans ++;                }            }        }        for(int i = 1; i <= n; i ++){            for(int j = 1; j <= n; j ++)            if(map[i][j] != '@') ans ++;        }        printf("Case %d: %d\n", k ++, ans);    }    return 0;}

对于迷宫类深搜来说。。。搜到某点。。应该想标记。。否则就会出现 1 -> 2 -> 1 这样的循环。。。。而你的程序也就会陷入死循环。。。 新思想get!

0 0