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

来源:互联网 发布:javascript的数据类型 编辑:程序博客网 时间:2024/06/05 04:02

红与黑(图的遍历)

目录

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..#.#....#.#..###.###...@...###.###..#.#....#.#..4559613

具体代码:

#include <iostream>#include <cstring>#include <algorithm>using namespace std;//移动的方向抽象成1与-1const 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复原,因为这里相当于遍历整个图,已走过的没必要再走一次。        }    }}