`
200830740306
  • 浏览: 105843 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

poj1979 深度遍历

阅读更多
问题重述
问题描述:
有一个长方形的房间里,是用方瓦覆盖的。每个方瓦的颜色是红色或黑色。一名男子正站在一个黑色瓷砖。他从他所站的方瓦上,可以转移到相邻的四个砖之一。但他无法进入红瓦,他只可以进入黑瓦。
编写一个程序来计算黑瓦数量,也就是他可以达到的方瓦数(重复上述动作)。输入:
输入包含多个数据集。一个数据集的包含有在开始的第一行的两个正整数W和H,W和H表示x和y方向上的方瓦数。 W和H的不超过20。之后有H行的数据集,其中每行包括W列字符。每个字符代表着瓷砖的颜色如下:
’.’ -黑色瓦片
‘#’-一个红色的瓷砖
‘@’-一黑砖上的人
该程序可以循环输入,当输入的W和H都为0时,程序终止。
输出:
有多少块黑瓦
Sample Input
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0
Sample Output
45
59
6
13
解题过程:
分析过程:
当读懂了题意后,很容易地就地发现这是一道典型的深度遍历的应用。所以在算法上就没有什么问题。当前要解决的就是数据的输入与存储处理问题。一看到矩阵的输入,我就想到了要用二维数组,然后对应的把字符转换为数字存储。考虑到在遍历过程中要判断边界问题,所以我就把数组的行列数再多加两行两列,以方便处理。
编程过程:
在数据的输入方面,我花了较长的时间,我刚开始是用scanf("%s",s);想把每一行的字符读取后,再去掉空格,最后再存进数组。但却发现是这种方式是不读取空格的。之后又想用gets(s);但发现去空格有点麻烦。最后才发现用getchar();就可以很简单地实现。
在数据的存储方面,我用二维数组存储对应的数字,并设置数组初始值为0;因为边界问题,我直接空出一圈不存储数据,使其为默认值,使得边界的处理变很很简单。
在调试的过程中,我犯了一些很低级的错误,花费了很多的时间。其一,break;只跳出当前循环,但我却在一个二层循环中直接使用,以为能跳出两层。其二,因为是循环输入与输出,需要每一趟都初始化。其三,遍历的时候是四个方向逐个访问,但我却因为顺手就用了else if,使得只访问一个方向。
做题收获:
此次编程,让我对字符串的输入处理更熟练,对二维数组做为函数参数的理解更深刻,对广度遍历的算法也更进一步掌握。
4.程序源码:
package middle;


import java.io.BufferedInputStream;
import java.util.Scanner;

/**
 *
 *poj1979
 * 这道题是数据结构的第一道,刚开始是用c语言做的,但后来其他题目我都用了java去写,
 * 所以现在只是简单把c语法转化为java法,统一一下编码而已
 * @author NC
 */
public class Poj1979 {

    private final static int MAXCOL = 22;
    private final static int MAXROW = 22;
    private static int[][] floor = new int[MAXROW][MAXCOL]; //最多是20行,20列,再加两行两列作为边界
    private static int[][] visited = new int[MAXROW][MAXCOL]; //标记是否访问过,默认没有访问过

    public static void main(String[] args) {

        Scanner scan = new Scanner(new BufferedInputStream(System.in));
        while (scan.hasNext()) {
            int col = scan.nextInt();
            int row = scan.nextInt();
            int i = 0, j = 0, k = 0;
            int count = 0;
            int flag = 0;
            char c;
            //读取数据
            if (col == 0 && row == 0) {
                break;
            }
            //因为是循环输入,所以每一次都得初始化
            for (i = 0; i < MAXROW; i++) {
                for (j = 0; j < MAXCOL; j++) {
                    floor[i][j] = 0;
                    visited[i][j] = 0;
                }
            }
            scan.nextLine();
            //一个一个读取字符,将符号转换为数字
            for (i = 1; i <= row; i++) {
                char[] ss = scan.nextLine().trim().toCharArray();
                for (j = 1; j <= col; j++) {
                    while (true) {
                        c = ss[j-1];
                        if (c == '.' || c == '#' || c == '@') {
                            break;
                        }
                    }
                    if (c == '.') {
                        floor[i][j] = 1;
                    } else if (c == '#') {
                        floor[i][j] = 2;
                    } else if (c == '@') {
                        floor[i][j] = 3;
                    }
                }
            }
            //找出人所站的位置
            flag = 0;
            for (i = 1; i <= row; i++) {
                for (j = 1; j <= col; j++) {
                    if (floor[i][j] == 3) {
                        flag = 1;
                        break; //要跳出两层
                    }
                }
                if (flag == 1) {
                    break;
                }
            }
            //深度遍历
            if (floor[i][j] == 3) {
                DFS(i, j);
            }
            //count the number of tiles he can reach from the initial tile
            count = 0;
            for (i = 1; i <= row; i++) {
                for (j = 1; j <= col; j++) {
                    if (visited[i][j] == 1) {
                        count++;
                    }
                }
            }
            //print the number of tiles he can reach from the initial tile
            System.out.println(count);
        }
    }

    static void DFS(int i, int j) {
        //标记访问过
        visited[i][j] = 1;
        //四个方向都要遍历,不能用else if
        if (floor[i][j + 1] == 1 && visited[i][j + 1] == 0) {
            DFS(i, j + 1);
        }
        if (floor[i][j - 1] == 1 && visited[i][j - 1] == 0) {
            DFS(i, j - 1);
        }
        if (floor[i + 1][j] == 1 && visited[i + 1][j] == 0) {
            DFS(i + 1, j);
        }
        if (floor[i - 1][j] == 1 && visited[i - 1][j] == 0) {
            DFS(i - 1, j);
        }
    }
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics