`
200830740306
  • 浏览: 109448 次
  • 性别: 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);
        }
    }
}


分享到:
评论

相关推荐

    POJ 1979 Red and Black(广搜与深搜两种解答)

    标题“POJ 1979 Red and Black”是一个编程竞赛题目,主要涉及的问题是算法设计,特别是搜索算法。在这个问题中,广度优先搜索(BFS)和深度优先搜索(DFS)这两种策略被用来解决特定的红黑树相关的问题。红黑树是一...

    poj2488——dfs深度优先遍历

    poj 2488——dfs深度优先遍历 //给行数列数,求问能否遍历,给出字典序的一种遍历

    POJ算法题目分类

    * 图的深度优先遍历和广度优先遍历:图的深度优先遍历和广度优先遍历是指遍历图的两种方式,如 poj1860、poj3259、poj1062、poj2253、poj1125、poj2240。 * 最短路径算法:最短路径算法是指计算图中两点之间的最短...

    poj题目分类

    * 图的深度优先遍历和广度优先遍历:例如 poj1860、poj3259、poj1062、poj2253、poj1125、poj2240。 * 最短路径算法:例如 Dijkstra、Bellman-Ford、Floyd、Heap+Dijkstra,例如 poj1860、poj3259、poj1062、poj...

    poj训练计划.doc

    - 图的深度优先遍历和广度优先遍历:用于探索图的所有节点,如`poj1860, poj3259`。 - 最短路径算法:如Dijkstra算法和Bellman-Ford算法,用于找到两点间的最短路径,如`poj1062, poj2253`。 - 最小生成树算法:...

    poj各种分类

    包括深度优先遍历(DFS)和广度优先遍历(BFS),用于探索图的所有节点,是解决许多图问题的基础,如poj1860和poj3259所示。 #### 最短路径算法 Dijkstra算法、Bellman-Ford算法和Floyd算法分别适用于无负权边、有...

    POJ题目简单分类(ACM)

    - **深度优先搜索**:如poj2488,常用于解决树或图的遍历问题。 - **广度优先搜索**:如poj3278,适用于寻找最短路径。 - **搜索技巧与剪枝**:优化搜索过程,避免无效计算,如poj2531。 5. **动态规划**: - *...

    acm poj300题分层训练

    如poj3278、poj2049、poj3083是图遍历的例子,poj1860、poj3259等则是最短路径问题,poj1789、poj2485等则涉及最小生成树。 3. **数据结构**:包括串、排序、简单并查集、哈希表、二分查找、哈夫曼树和堆。poj1035、...

    经典 的POJ 分类

    - POJ 2488、POJ 3083:利用DFS遍历图或树。 - POJ 3009、POJ 1321:基于DFS的问题求解。 #### 广度优先搜索 (BFS) - **题目示例**: - POJ 2251:BFS的应用场景。 #### 其他搜索算法 - **题目示例**: - POJ ...

    POJ2676-Sudoku

    2. **深度优先搜索(DFS)**:一种常见的解决数独问题的算法是深度优先搜索。从第一个空白单元格开始,尝试填充1到9的数字,如果在某一步无法进行(即违反了数独规则),则回溯到上一步,尝试下一个数字。 3. **...

    强大的poj分类

    常用的搜索算法有深度优先搜索(DFS)、广度优先搜索(BFS)、贪心算法、回溯算法等。 **重要性**:搜索算法是解决许多复杂问题的有效手段。例如,在游戏AI、路径规划等领域有着广泛的应用。 **示例题目**: - POJ...

    POJ2531-Network Saboteur

    2. **图的遍历**:DFS和BFS是解决图问题的常用方法,它们可以用来寻找特定路径或计算节点之间的最短路径。 3. **网络破坏策略**:题目可能要求玩家找出最小数量的节点,破坏这些节点将导致整个网络崩溃。这需要对图...

    acm新手刷题攻略之poj

    - 搜索算法包括深度优先搜索(DFS)、广度优先搜索(BFS)等,适用于解决图遍历问题。 4. **模拟** - 推荐题目:[poj1068](https://vjudge.net/problem/POJ-1068)、[poj2632](https://vjudge.net/problem/POJ-2632)、...

    POJ1039-Pipe

    POJ1039-Pipe可能需要应用到的算法包括但不限于深度优先搜索(DFS)、广度优先搜索(BFS)、动态规划、贪心算法或图的遍历算法。 4. **图论**:由于题目名为"Pipe",很可能涉及到图的结构,比如管道之间的连接可以...

    POJ题目及答案

    例如,数据结构部分可能包括链表、栈、队列、树、图等经典结构的运用,如二叉树的遍历、图的深度优先搜索和广度优先搜索等;在图论方面,可能会遇到最小生成树、最短路径等问题;动态规划则常用于解决背包问题、最长...

    POJ3126-Prime Path

    3. **深度优先搜索(DFS)**或**广度优先搜索(BFS)**:这些是图遍历的经典算法,用于寻找所有可能的路径。在这个问题中,可以使用DFS或BFS来探索从起点到其他节点的所有素数路径。 4. **动态规划(Dynamic ...

    POJ1753-Flip Game

    2. **广度优先搜索**:使用BFS遍历所有可能的操作序列。每个节点代表一次操作后的棋盘状态,边连接代表可行的操作。通过BFS可以找到达到目标状态的最短路径,即最少的翻转次数。 三、DFS+枚举解决方案 1. **深度...

    POJ3733-Changing Digits【DFS+强剪枝】

    【标签】中的"POJ 3733 Changing Digits"指明了这个题目在POJ平台上的编号和主题,"DFS"代表深度优先搜索,是一种用于遍历或搜索树或图的算法,它沿着树的深度方向逐层探索,直到找到目标节点或者搜索完整个树。...

    POJ1011-Sticks

    一种常见的方法是使用深度优先搜索(DFS)或广度优先搜索(BFS)来构建线段之间的连接,并通过并查集(Disjoint Set)数据结构来判断是否存在不相交的集合。 1. **数据结构**:首先,我们需要用数组或者链表存储...

    ACM 比赛 POJ的训练计划,,,非常不错,关键在于坚持

    然后,需要学习图算法,如深度优先遍历、广度优先遍历、最短路径算法和最小生成树算法等。最后,需要学习数据结构,如串、排序、堆和哈希表等。 ACM 比赛 POJ 训练计划旨在帮助选手提高算法和数据结构的能力,涵盖...

Global site tag (gtag.js) - Google Analytics