POJ 1979 红与黑

题目地址: http://poj.org/problem?id=1979  或者  https://vjudge.net/problem/OpenJ_Bailian-2816

        Red and Black
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 46793   Accepted: 25201

Description

There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles. 

Write a program to count the number of black tiles which he can reach by repeating the moves described above. 

Input

The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20. 

There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows. 

'.' - a black tile 
'#' - a red tile 
'@' - a man on a black tile(appears exactly once in a data set) 
The end of the input is indicated by a line consisting of two zeros. 

Output

For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself).

Sample Input

6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0

Sample Output

45
59
6
13

 一开始我的代码没有在每次输入前将地板置零,导致在输入11 6这组数据时出错,因为在之前输入11 9 这组数据时已经将11 6 外面的地板置为了.或者#, 之后

再测试11 6 时,由于没有置空地板,所以11 9 时在11 6 外面的地板仍然保留了下来,导致11 6 这组测试数据的结果产生错误。

 正确代码:
#include <iostream>

using namespace std;

char Floor[30][30];    //地板
int visited[30][30];    //访问标记,0表示未访问,1表示已访问
int num = 0;   //瓷砖数

void dfs(int i, int j)
{
    visited[i][j] = 1;    //标记为已访问
    ++num;
    if (Floor[i - 1][j] == '.' && !visited[i - 1][j])
        dfs(i - 1, j);    //往上走
    if (Floor[i][j - 1] == '.' && !visited[i][j - 1])
        dfs(i, j - 1);    //往左走
    if (Floor[i][j + 1] == '.' && !visited[i][j + 1])
        dfs(i, j + 1);    //往右走
    if (Floor[i + 1][j] == '.' && !visited[i + 1][j])
        dfs(i + 1, j);    //往下走

}


int main()
{
    int W, H;
    while (cin >> W >> H && (W != 0 || H != 0))    //W是列数,H是行数
    {
        num = 0;    //将访问的黑瓷砖数置零

        for (int i = 0; i < 30; ++i)
            for (int j = 0; j < 30; ++j)
                Floor[i][j] = '#';        //将地板置零

        for (int i = 0; i < 30; ++i)
            for (int j = 0; j < 30; ++j)
                visited[i][j] = 0;        //将地板的访问状态置零

        int start_i, start_j;    //起点坐标

        //创建地板,二维数组的第1行和第1列不用,并且地板初始为30×30,足够大,
        //从而避免初始点落在边界上调用dfs时产生的数组越界问题
        for (int i = 1; i <= H; ++i)
            for (int j = 1; j <= W; ++j)
            {
                cin >> Floor[i][j];
                if (Floor[i][j] == '@')    //记录下起点坐标
                {
                    start_i = i;
                    start_j = j;
                }
            }

        dfs(start_i, start_j);
        cout << num << endl;

    }

    return 0;

}
原文地址:https://www.cnblogs.com/FengZeng666/p/10381694.html