2386.LAKE COUNTING 湖泊计数--BFS

1648545-20190709093209920-719354513.png

顺便训练自己的英语:
因为近期下雨,农家John 的农场有很多水坑(用一个NM矩阵表示| represent 代表、rectangle 矩阵),每一个区域表示形式为水(w)或者土地(.),农夫jhon 想指出在他的农村多少个已经形成的水坑,一个水坑是由一个水和连接在一起的八个邻居区域形成的
给一个农场的示意图(diagram 示意图 图示),推测有多少个水坑(square 正方形)
输入:
第一行两个数 N 和M
第二行M 个字符一行
输出:
数量
百度翻译
由于最近的降雨,水聚集在农民约翰农场的各个地方,由一个n x m(1<=n<=100;1<=m<=100)的矩形表示。每个广场都有水(“W”)或旱地(“.”)。农夫约翰想知道他田里形成了多少池塘。池塘是一组相连的正方形,其中有水,一个正方形被认为是邻近八个邻居。给一张农夫约翰田地的图表,确定他有多少池塘。

解法一:

import java.util.Scanner;
public class Main {
    static char[][] c;
    static boolean flag[][];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int N = sc.nextInt();
            int M = sc.nextInt();   
            c = new char[N][M];                                 //赋值
            flag = new boolean[c.length][c[0].length];          //赋值
            for (int i = 0; i < N; i++) {
                String s = sc.next();
                c[i] = s.toCharArray();                         //赋值
                for (int j = 0; j < M; j++) {
                    flag[i][j] = false;                         //初始化
                }
            }
            int s = 0;
            for (int i = 0; i < c.length; i++) {
                for (int j = 0; j < c[0].length; j++) {
                    if (flag[i][j] != true) {                   //如果这个值没有被读过
//                      flag[i][j] = true;      多余的 因为下面函数会再次赋值 如果在这里赋值会导致每个值不能通过               //赋值已读状态
                        if (c[i][j] == 'W') {                   //如果是w 即进行深度遍历
                            dfs(c, i, j, flag);                 //满足条件都赋值
                            s++;
                        }
                    }
                }
            }
            System.out.println(s);
        }
    }
    public static void dfs(char[][] arr, int x, int y, boolean[][] temp) {
        if (x < 0 || x >= c.length || y >= c[0].length || y < 0)                //超出范围就跳出
            return;
        if (temp[x][y] == true)                                                 // 说明已经访问了
            return;
        if (arr[x][y] == '.') {                                                 //为.即不满足条件
            temp[x][y] = true;                                                  //并赋予已读状态
            return;
        }
        temp[x][y] = true;                                                      //留下来的都是未读w
        dfs(arr, x, y + 1, temp);                                               // 把周围符合条件的位置遍历赋值true
        dfs(arr, x, y - 1, temp);
        dfs(arr, x + 1, y, temp);
        dfs(arr, x + 1, y + 1, temp);
        dfs(arr, x + 1, y - 1, temp);
        dfs(arr, x - 1, y, temp);
        dfs(arr, x - 1, y + 1, temp);
        dfs(arr, x - 1, y - 1, temp);
    }
}

解法二:
直接将 W 改为 . !!!以表示已读

import java.util.Scanner;
public class Main {
    static char[][] field;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int N = sc.nextInt();
            int M = sc.nextInt();
            field = new char[N][M]; // 赋值
            for (int i = 0; i < N; i++) {
                String s = sc.next();
                field[i] = s.toCharArray(); // 赋值
            }
            int s = 0;
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < M; j++) {
                    if (field[i][j] == 'W') {
                        dfs(i, j, N, M);
                        s++;
                    }
                }
            }
            System.out.println(s);
        }
    }
    public static void dfs(int x, int y, int N, int M) {
        field[x][y] = '.';
        for (int i = -1; i < 2; i++) {
            for (int j = -1; j < 2; j++) {
                int nx = x + i;
                int ny = y + j;
                if (0 <= nx && nx < N && 0 <= ny && ny < M && field[nx][ny] == 'W')
                    dfs(nx, ny, N, M);
            }
        }
    }
}

转载于:https://www.cnblogs.com/cznczai/p/11148086.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值