zoukankan      html  css  js  c++  java
  • 用dfs遍历联通块(优化)

    一、题目(CF 598D)

    输入一个n x m的字符矩阵,求从某个空点出发,能碰到多少面墙壁,总共询问k次。(3 ≤m,n ≤1000,1 ≤ k ≤ min(nm,100 000)) 

    二、解题思路

    用DFS找连通分量:从每个“.”格子出发,递归遍历与之相邻的“*”格子,且写上相同的联通分量(即代码中的blocks数组),同时统计该联通分量边界墙壁面数。由于存在多次查询,我们用blocks[i][j]记录格子(i,j)所在的联通分量标号,用res[i]表示联通分量i的边界墙壁面数。

    三、代码实现

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<string.h>
     4 #include<stdbool.h>
     5 using namespace std;
     6 
     7 const int maxn = 1000 + 10;
     8 const int maxm = 1000 + 10;
     9 const int maxk = 100000 + 10;
    10 const int maxx = 1000000 + 10;
    11 int n, m;
    12 char maze[maxn][maxm];
    13 bool vis[maxn][maxm];
    14 int blocks[maxn][maxm];
    15 int res[maxx];
    16 int dx[] = { -1,0,1,0 }, dy[] = { 0,1,0,-1 };
    17 int flag = 0;
    18 
    19 void dfs(int x, int y, int flag,int& sum)   //sum传引用
    20 {
    21     vis[x][y] = true;
    22     blocks[x][y] = flag;
    23     for (int i = 0; i < 4; i++)
    24     {
    25         int xx = x + dx[i]; int yy = y + dy[i];
    26         if (xx >= 0 && xx < n && yy >= 0 && yy < m && (!vis[xx][yy]))
    27         {
    28             if (maze[xx][yy] == '*')
    29                 sum++;
    30             else
    31                 dfs(xx, yy, flag,sum);
    32         }
    33     }
    34 }
    35 int main()
    36 {
    37     int k;
    38     scanf("%d%d%d", &n, &m, &k);
    39     memset(vis, 0, sizeof(vis));
    40 
    41     for (int i = 0; i < n; i++)
    42         for (int j = 0; j < m; j++)
    43             cin >> maze[i][j];
    44 
    45     for (int i = 0; i < n; i++)
    46         for (int j = 0; j < m; j++)
    47         {
    48             if (maze[i][j] == '.' && (!vis[i][j]))
    49             
    50             {
    51                 int sum = 0;
    52                 dfs(i, j, ++flag,sum);
    53                 res[flag] = sum;
    54             }
    55         }
    56 
    57     while (k--)
    58     {
    59         int sx, sy;
    60         scanf("%d%d", &sx, &sy);
    61         printf("%d
    ", res[blocks[sx - 1][sy - 1]]);
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    软件体系架构复习要点
    Operating System on Raspberry Pi 3b
    2019-2020 ICPC North-Western Russia Regional Contest
    2019 ICPC ShenYang Regional Online Contest
    2019 ICPC XuZhou Regional Online Contest
    2019 ICPC NanChang Regional Online Contest
    2019 ICPC NanJing Regional Online Contest
    Codeforces Edu Round 72 (Rated for Div. 2)
    Codeforces Round #583 (Div.1+Div.2)
    AtCoder Beginning Contest 139
  • 原文地址:https://www.cnblogs.com/lfri/p/9655368.html
Copyright © 2011-2022 走看看