zoukankan      html  css  js  c++  java
  • DFS/BFS-A

    A - Red and Black

    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.

    InputThe 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)
    OutputFor 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
    
    
    题目大意:“#”相当于不能走的陷阱或墙壁,“.”是可以走的路。从@点出发,统计所能到达的地点总数
    
    
     1 //并查集解决
     2 #include<iostream>
     3 using namespace std;
     4 
     5 const int h = 22;
     6 char map[h][h];
     7 int  key[h*h];
     8 int rrank[h*h];
     9 int  n,m,dx,dy;
    10 
    11 int find(int a){
    12     return a==key[a]? a : key[a]=find(key[a]);
    13 }
    14 
    15 void key_union(int a,int c){
    16     int fa = find(a);
    17     int fc = find(c);
    18     if(rrank[fa]>rrank[fc])
    19         key[fc] = fa;
    20     else{
    21         key[fa] = fc;
    22         if(rrank[fa]==rrank[fc])
    23             rrank[fc]++;
    24     }
    25 }
    26 
    27 int num(int a){
    28     int k = find(a);
    29     int ans = 0;
    30     for(int i=1;i<=m;i++)
    31         for(int j=1;j<=n;j++)
    32             if(find(i*n+j)==k)
    33                 ans++;
    34                 
    35     return ans;
    36 }
    37 
    38 int main()
    39 {
    40     while(scanf("%d %d",&n,&m)!=EOF){
    41         if(n==0&&m==0)    break;
    42         for(int i=1;i<=m;i++){
    43             cin.get();
    44             for(int j=1;j<=n;j++){
    45                 scanf("%c",&map[i][j]);
    46                 if(map[i][j]!='#')    key[i*n+j] = i*n+j;
    47                 else                key[i*n+j] = 0;
    48                 if(map[i][j]=='@'){//找到@的坐标 
    49                     dx = i;
    50                     dy = j;
    51                     map[i][j] = '.';
    52                 }
    53             }
    54         }
    55 
    56         for(int i=1;i<m;i++){
    57             for(int j=1;j<n;j++){
    58                 if(key[i*n+j]){
    59                     if(key[i*n+j+1])  
    60                         key_union(i*n+j,i*n+j+1);
    61                     if(key[i*n+n+j])
    62                         key_union(i*n+n+j,i*n+j);
    63                 }
    64             }
    65             if(key[i*n+n])
    66                 if(key[i*n+2*n])
    67                     key_union(i*n+2*n,i*n+n);
    68         }
    69         for(int i=1;i<n;i++)
    70             if(key[m*n+i])
    71                 if(key[m*n+i+1])
    72                     key_union(m*n+i,m*n+i+1);    
    73                     
    74         int ans = num(dx*n+dy);
    75         printf("%d
    ",ans);
    76     }
    77 }
    
    
     1 //DFS解决
     2 #include<iostream>
     3 using namespace std;
     4 
     5 int mov[4][2] = {-1,0,1,0,0,-1,0,1};
     6 int sum,w,h;
     7 char s[21][21];
     8 
     9 void dfs(int x,int y){
    10     sum++;//计数 
    11     s[x][y] = '#';
    12     for(int i=0;i<4;++i){//四个方向前进 
    13         int tx = x+mov[i][0];
    14         int ty = y+mov[i][1];
    15 
    16         if(s[tx][ty]=='.' && tx>=0 && tx<h && ty>=0 && ty<w)
    17             dfs(tx,ty);//判断该点可行后进入dfs 
    18     }
    19 }
    20 
    21 int main()
    22 {
    23     int x,y;
    24     while(scanf("%d %d",&w,&h)!=EOF){
    25         if(w==0&&h==0)    break;
    26         for(int i=0;i<h;i++){
    27             cin.get();
    28             for(int j=0;j<w;j++){
    29                 scanf("%c",&s[i][j]);
    30                 if(s[i][j]=='@'){//起点 
    31                     x = i;
    32                     y = j;
    33                 }
    34             }
    35         }
    36         sum = 0;
    37         dfs(x,y);
    38         printf("%d
    ",sum);
    39     }
    40     return 0;
    41 }
     1 //BFS解决
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 
     5 char room[23][23];
     6 int dir[4][2] = { //左上角的坐标是(0,0) 
     7     {-1, 0},     //向左 
     8     {0, -1},     //向上 
     9     {1, 0},     //向右 
    10     {0, -1}        //向下 
    11 };
    12 
    13 int Wx, Hy, num;
    14 #define check(x, y)(x<Wx && x>=0 && y>=0 && y<Hy)    //是否在room中
    15 struct node{int x, y};
    16 
    17 void BFS(int dx, int dy){
    18     num = 1;
    19     queue<node> q;
    20     node start, next;
    21     start.x = dx;
    22     start.y = dy;
    23     q.push(start);//插入队列 
    24     
    25     while(!q.empty()){//直到队列为空 
    26         start = q.front();//取队首元素,即此轮循环的出发点 
    27         q.pop();//删除队首元素(以取出) 
    28         
    29         for(int i=0; i<4; i++){//往左上右下四个方向逐一搜索 
    30             next.x = start.x + dir[i][0];
    31             next.y = start.y + dir[i][1];
    32             if(check(next.x, next.y) && room[next.x][next.y]=='.'){ 
    33                 room[next.x][next.y] = '#';//标记已经走过 
    34                 num ++;//计数 
    35                 q.push(next);//判断此点可行之后,插入队列,待循环判断 
    36             }
    37         }
    38     }
    39 } 
    40 
    41 int main(){
    42     int x, y, dx, dy;
    43     while(~scanf("%d %d",&Wx, &Hy)){
    44         if(Wx==0 && Hy==0)
    45             break;
    46         for(y=0; y<Hy; y++){
    47             for(x=0; x<Wx; x++){
    48                 scanf("%d",&room[x][y]);
    49                 if(room[x][y] == '@'){//找到起点坐标 
    50                     dx = x;
    51                     dy = y;
    52                 }
    53             }
    54         }
    55         num = 0;//初始化 
    56         BFS(dx, dy);
    57         printf("%d
    ",num);
    58     }
    59     return 0;
    60 }
    
    
    
    
  • 相关阅读:
    如何将List<T>转换相应的Html(xsl动态转换)(一)
    如何将List<T>转换相应的Html(xsl动态转换)(二)
    JavaScript设计模式之一Interface接口
    架构设计资源
    将ASP.NET MVC 2.0 部署在IIS6和IIS7上的教程
    如何将List<T>转换相应的Html(xsl动态转换)(一)
    步步为营 .NET 代码重构学习笔记 六
    如何将List<T>转换相应的Html(xsl动态转换)(二)
    模式资源
    Entity Framework Code First
  • 原文地址:https://www.cnblogs.com/0424lrn/p/12230508.html
Copyright © 2011-2022 走看看