HDOJ Red and Black

本文介绍了一种在红黑方格地图中寻找可达黑色方格数量的算法问题,通过深度优先搜索(DFS)和广度优先搜索(BFS)两种方法实现,并提供了完整的代码示例。
 

Red and Black

http://acm.hdu.edu.cn/diy/contest_showproblem.php?cid=12573&pid=1001

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 9   Accepted Submission(s) : 8
Font: Times New Roman | Verdana | Georgia
Font Size: ← →

Problem 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)

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

Source

Asia 2004, Ehime (Japan), Japan Domestic
 
 
 
深度优先搜索代码如下:
 
//深度优先搜索
#include<iostream>
using namespace std;
const int N=25;
char map[N][N];
int visited[N][N];
int cnt;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; //方向
void DFS(int r,int c){
     if(map[r][c]=='#'||visited[r][c]==1)  return;  //此路不通或已搜索过
     visited[r][c]=1;
     cnt++;
     for(int i=0;i<4;i++)
        DFS(r+d[i][0],c+d[i][1]);
     return;
}
int main(){
    int row,col;  //行数和列数
    int r,c; //始点的行数和列数
    while(scanf("%d%d%*c",&col,&row)==2){
         if(col==0 && row==0 )  break;
         for( int i=1;i<=row;i++){
              for(int  j=1;j<=col;j++){
                   scanf("%c",&map[i][j]);
                   if(map[i][j]=='@'){
                       r=i;
                       c=j;
                   }             
              }       
              getchar();  
         }
         for(int  i=0;i<=col+1;i++)
                 map[0][i]=map[row+1][i]='#';
         for(int i=1;i<=row;i++)
                 map[i][0]=map[i][col+1]='#';
         for(int i=0;i<=row+1;i++)
             for(int j=0;j<=col+1;j++)
                 visited[i][j]=0;
          cnt=0;
          DFS(r,c);
          printf("%d\n",cnt);                                   
    }
return 0;
}
 
代码改为这样也可以
 
 

//深度优先搜索
#include<iostream>
using namespace std;
const int N=25;
char map[N][N];
int visited[N][N];
int cnt;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; //方向
int row,col;  //行数和列数
void DFS(int r,int c){
     if(r<=row && r>=1 && c<=col && c>=1){
        if(map[r][c]=='#'||visited[r][c]==1)  return;  //此路不通或已搜索过
           visited[r][c]=1;
           cnt++;
        for(int i=0;i<4;i++)
           DFS(r+d[i][0],c+d[i][1]);
     }
     return;
}
int main(){
    int r,c; //始点的行数和列数
    while(scanf("%d%d%*c",&col,&row)==2){
         if(col==0 && row==0 )  break;
         for( int i=1;i<=row;i++){
              for(int  j=1;j<=col;j++){
                   scanf("%c",&map[i][j]);
                   if(map[i][j]=='@'){
                       r=i;
                       c=j;
                   }             
              }       
              getchar();  
         }
         /*for(int  i=0;i<=col+1;i++)
                 map[0][i]=map[row+1][i]='#';
         for(int i=1;i<=row;i++)
                 map[i][0]=map[i][col+1]='#'; */
         for(int i=1;i<=row;i++)
             for(int j=1;j<=col;j++)
                 visited[i][j]=0;
          cnt=0;
          DFS(r,c);
          printf("%d\n",cnt);                                   
    }
return 0;
}

 

下面是广度优先搜索:

#include<iostream>
#include<queue>
using namespace std;
const int N=25;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int row,col;  //行与列
int cnt;  //计数
char map[N][N];
struct Node{
       int x,y;
};
Node no,p;
void BFS(int r,int c){
     queue<Node>q;
     no.x=r;
     no.y=c;
     map[r][c]='#';  //搜索过的点置为#
     cnt++;
     q.push(no);
     while(!q.empty()){
          no=q.front();
          q.pop();
          for(int i=0;i<4;i++){
              int x=no.x+d[i][0],y=no.y+d[i][1];
              if(x>=1 && x<=row && y>=1 && y<=col){
                   if(map[x][y]=='.'){  
                         p.x=x;
                         p.y=y;
                         cnt++;
                         map[x][y]='#';
                         q.push(p);   
                   }
              }
          }                                  
     }
}
int main(){
    int r,c;  //始点的行号与列号
    while(scanf("%d%d%*c",&col,&row)!=EOF){
         if(col==0 && row==0 )  break;
         for(int i=1;i<=row;i++){
             for(int j=1;j<=col;j++){
                 scanf("%c",&map[i][j]);
                 if(map[i][j]=='@'){
                      r=i;
                      c=j;
                 }
             }
                 getchar();       
         } 
          cnt=0;       
         BFS(r,c);
         printf("%d\n",cnt);                                                                         
    }  
    return 0;
}

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值