POJ1979 /Openjudge1818 Red and Black解题报告(深度优先搜索,图的遍历)

红与黑(图的遍历)

目录

1.题目分析
2.dfs遍历与路径的差别
3.题目中文翻译
4.测试数据
5.具体代码

题目分析:

这道题是一道类似于图的遍历的题目,用的方法就是DFS(深度优先搜索),刚开始看题的时候不小心把题目意思给误解了,以为求的是找一条路径求这条路径上能走过的黑色瓷砖的最大数,不用想,这肯定超时了。
其实这道题只需判定能走到哪些黑色瓷砖,不需要死死的找一条能走到所有黑色瓷砖的路线,而是可以选择多条路线(比如走到一个点这个点往上只有一个瓷砖,我们可以往上走一步,然后返回,再在这个点选择其余的方向),当各个路线(类似于各种方案)都结束时所有走过的黑色瓷砖就都被标记了。

图的遍历和在图上找路径的差别

遍历:

①当碰到边界条件时返回上一步并且不需要还原上一步标记过的点。
②搜索的方向不唯一。

找路径:

①碰到边界条件时需要返回上一步并且还原上一步标记过的点。
②搜索的方向唯一。

中文翻译

描述
有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
输入
包括多个数据集合。每个数据集合的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下
1)‘.’:黑色的瓷砖;
2)‘#’:白色的瓷砖;
3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
当在一行中读入的是两个零时,表示输入结束。
输出
对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。

测试数据:

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

45
59
6
13

具体代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
//移动的方向抽象成1与-1
const int dx[] = {-1,0,1,0};
const int dy[] = {0,-1,0,1};
int ans = 0;//走过的黑色瓷砖
char s[20][20];//记录图
int vis[20][20];//标记瓷砖是否走过
int r,c;//边界
void dfs(int r,int c);
int main()
{

    int r1 = 0,c1 = 0;//初始化
    while(cin>>c>>r&&c){
        ans = 0;
    for(int i=0;i<r;i++)
        for(int j=0;j<c;j++)
        {
            cin>>s[i][j];
            vis[i][j]=0;
            if(s[i][j]=='@')
            {
                r1 = i;
                c1 = j;
            }
        }
    dfs(r1,c1);
    cout<<ans+1<<endl;//最后要加上第一个瓷砖@
    }
    return 0;
}
void dfs(int r2 , int c2)
{
    for(int i=0;i<4;i++)//上下左右四个方向
    {
        if((r2+dx[i]>=0)&&(r2+dx[i]<r)&&(c2+dy[i]>=0)&&(c2+dy[i]<c)&&(vis[r2+dx[i]][c2+dy[i]]==0)&&(s[r2+dx[i]][c2+dy[i]]=='.'))//判定边界条件和是否能走
        {
            ans++;
            vis[r2+dx[i]][c2+dy[i]]=1;//标记已走过
            dfs(r2+dx[i],c2+dy[i]);
            //这里没必要将vis复原,因为这里相当于遍历整个图,已走过的没必要再走一次。

        }
    }
}
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/Link_Ray/article/details/77619801
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞