sincerit 地、颜色、魔法(DFS+逆向思考)

链接:https://ac.nowcoder.com/acm/contest/218/A
来源:牛客网

现在,你作为一名新星鹏洛客,找到了一块绝佳的修炼地。这块地方可以被描述成一个 n x m 的矩形。你已经在这块地中的一些位置打好了标记。接下去,就该对整块地赋予你的颜色了。一个位置能被赋予你的颜色,当且仅当满足以下条件之一:
1. 这个位置被打上了标记
2. 这个位置在不经过被打标记的位置的情况下与边界不连通(这个图是四联通的)。换句话说,如果你从这个位置开始,在不经过被打标记的位置,且只能向上下左右四个方向移动的情况下永远不能走到地图的边界,那么这个位置符合条件
现在,你的好基友想知道,你能为多少个位置赋予你自己的颜色呢?
输入描述:
第一行包含两个正整数 n, m ,表示地图的长和宽。
接下去 n 行,每行一个长为 m 的字符串,表示地图的一行。
其中 表示该位置未被打标记; 表示该位置被打了标记。
保证地图仅由 和 构成。
输出描述:
输出仅一行,包含一个整数,表示你的答案。
示例1
输入
复制
4 4

.###
.#.#
.###
输出
复制
9
备注:
1 ≤ n x m ≤ 10^6

逆向思考:从四条边上的点出发开始搜,这些点能到达的点都一定不符合题意
这里有个开数组的方式就是n*m <= 10^6 行列不知道多大,那就用string去开空间

#include <stdio.h>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e6+5;
string map[N];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int n, m;
int ans = 0;
void DFS(int x, int y) {
  if (map[x][y] == '#') return;
  map[x][y] = '#'; // 不放到下面的if里是因为这里可以判断开始搜索的的位置是否符合条件 
  ans++;
  for (int i = 0; i < 4; i++) {
    int nx = x + dx[i];
    int ny = y + dy[i];
    if (nx >= 0 && nx < n && ny >= 0&& ny < m) {
      DFS(nx, ny);
    }
  }
}
int main() {
  scanf("%d%d", &n, &m);
  ans = 0;
  for (int i = 0; i < n; i++) cin >> map[i];
  for (int i = 0; i < n; i++) {
    DFS(i, 0);
    DFS(i, m-1);
  }
  for (int j = 0; j < m; j++) {
    DFS(0, j);
    DFS(n-1, j);
  }
  cout << n*m - ans << "\n";
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值