zoukankan      html  css  js  c++  java
  • HDU 1312:Red and Black(DFS搜索)

     

                   HDU 1312:Red and Black

    Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u
     

    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

    题解:本题还是DFS搜索(上下左右),只是增加一个计数器,计算可以走的地方的个数。
          规定地图中有可通行的位置,也有不可通行的位置,已知起点,求起点的与它相连成一片的部分,在这道题里输出相连的位置的数目。
        从起点开始,遍历每一个到达的点的四个方向(不再是八个),到达一个位置就将这个位置的字符变成不可走的'#',并且计数+1。其实就是计数将可走变成不可走的操作进行了多少次。
    这样可以不用担心走过了还会重复。
     
     AC
    代码:如果你看过我的上一篇你一定会懂
    #include<cstdio>
    #include<cstring>
    char pic[110][110];
    int m,n,total;
    int idx[110][110];
    
    void dfs(int r,int c,int id)
    {
        if(r<0||r>=m||c<0||c>=n)
            return;
        if(idx[r][c]==666||pic[r][c]!='.')
            return;
        idx[r][c]=id;
        total++;
        for(int dr=-1; dr<=1; dr++)
            for(int dc=-1; dc<=1; dc++)
                if(dr==0||dc==0)
                    dfs(r+dr,c+dc,id);
    }
    int main()
    {
        int i,j;
        while(scanf("%d%d",&n,&m)==2&&m&&n)
        {
            for(i =0; i<m; i++)
                scanf("%s",pic[i]);
            memset(idx,0,sizeof(idx));
            total=0;
            for(i=0; i<m; i++)
                for(j=0; j<n; j++)
                {
                    if(pic[i][j]=='@')
                    {
                        pic[i][j]='.';
                        dfs(i,j,666);
                    }
                }
            printf("%d
    ",total);
        }
        return 0;
    }
     
     
     
    这个是我在其他博客上看得到的方法,用#填充,可以一试!
     
    #include <iostream>
    using namespace std;
    char a[25][25];
    int n,m,total;
    int dr[4] = {0,1,0,-1};//行变化
    int dc[4] = {1,0,-1,0};//列变化
    //上面的原来一直不会用,知道的话非常方便
    bool judge(int x,int y)
    {
        if(x<1 || x>n || y<1 || y>m)
            return 1;
        if(a[x][y]=='#')
            return 1;
        return 0;
    }
    void dfs(int r,int c)
    {
        total++;
        a[r][c]='#';               //走过一次,“。”变为“#”,避免重复
        for(int k=0; k<4; k++)
        {
            int lr = r + dr[k];
            int lc = c + dc[k];
            if(judge(lr,lc))
                continue;
            dfs(lr,lc);
        }
    
    }
    int main()
    {
        while(cin>>m>>n&&m&&n)
        {
            int i,j,x,y;
            total=0;
            for(i=1; i<=n; i++)
                for(j=1; j<=m; j++)
                {
                    cin>>a[i][j];
                    if(a[i][j]=='@')             //这里必须用变量x,y
                        x=i,y=j;
    
                }
            dfs(x,y);
            cout<<total<<endl;
        }
        return 0;
    }
     
  • 相关阅读:
    加关注
    UI设计
    敏捷开发
    java书箱
    怎么优化JAVA程序的执行效率和性能?
    sql访注入
    Matlab中plot函数全功能解析
    matlab分割背景与物体
    ssh免密码登录
    c++字符串详解(转)
  • 原文地址:https://www.cnblogs.com/hfc-xx/p/4666884.html
Copyright © 2011-2022 走看看