sincerit 地、顏色、魔法(DFS+逆向思考)
阿新 • • 發佈:2018-11-30
連結: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;
}