“Red and Black(红黑瓷砖),ZOJ2165”的一种解法

一、题目

1.1题目编号:ZOJ2165

详见:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2165

1.2题目描述:

有一个长方形的房间,房间里的地面上布满了正方形的瓷砖,瓷砖要么是红色,要么是黑色。一男子站在其中一块黑色的瓷砖上。男子可以向他四周的瓷砖上移动,但不能移动到红色的瓷砖上,只能在黑色的瓷砖上移动。

本题的目的就是要编写程序,计算他在这个房间里可以到达的黑色瓷砖的数量。

 1.3输入描述

输入文件中包含多个测试数据。每个测试数据的第1 行为两个整数W和H,分别表示长方形房间里x方向和y方向上瓷砖的数目。W和H的值不超过20。接下来有H 行,每行有W个字符,每个字符代表了瓷砖的颜色,这些字符的取值及含义为:

1) '.' - 黑色的瓷砖;

2) '#' - 红色的瓷砖;

3) '@' - 表示该位置为黑色瓷砖,且一名男子站在上面,注意每个测试数据中只有一个

'@'符号。

输入文件中最后一行为两个0,代表输入文件结束。

1.4 输出描述

对输入文件中每个测试数据,输出占一行,为该男子从初始位置出发可以到达的黑色瓷砖的数目(包括他初始时所处的黑色瓷砖)。样例如下:

 “Red and Black(红黑瓷砖),ZOJ2165”的一种解法_第1张图片

 

二、思路

由于需要求解的是从当前位置可以达到的所有黑色瓷砖的数量,显然可以利用深度搜索实现。解法比较直观,可以作为一个比较典型的DFS案例。

通过递归实现DFS的关键在于1)判定退出条件,2)施行必要的剪枝,3)确认是否需要在进入下一级递归前,从递归返回时执行必要的调整

本题比较简单,Mr. Pospro将结合代码注释进行必要的解释。

 

三、解答

/*
红与黑(Red and Black), ZOJ2165, POJ1979
2016.05.18 Wed Sunny by Pospro
详见博客 http://blog.csdn.net/pospro
*/
#include 
#include 
#define MAXN 22

int N; //rows
int M; //columns
int cnt; //the number of ceramics he can reach;
char map[MAXN][MAXN];
int fx[8]={-1,0,0,1,1,0,0,-1}; //两个作为一组,分别表示上右下左四个方向

void DFS(int x, int y)
{
    int nextx, nexty;
    int i,j;

    map[x][y]='*'; //先把当前格设为已访问过
    for(i=0;i<8;i=i+2) //按照上右下左的顺序,朝四个方向尝试
    {
        nextx=x+fx[i];
        nexty=y+fx[i+1];

        if(nextx<0||nextx>=N||nexty<0||nexty>=M||map[nextx][nexty]!='.')
            continue; //满足以上任一个条件,则说明此路不通,换方向再试试吧

        cnt++; //如果到达这里,则说明此处也是黑瓷砖,计数加1,并启动新的搜索
        DFS(nextx, nexty);
    }
}

int main()
{
    int i,j;
    int startx, starty; //开始位置,即@所在位置
    while(1)
    {
        scanf("%d%d",&M, &N); //注意审题,题目的输入是先列后行!
        if(M==0&&N==0)
            break;
        cnt=1; //新开始,重新置1
        memset(map,0,sizeof(map)); //清空地图
        for(i=0;i



你可能感兴趣的:(编程实例,算法)