1. 程式人生 > >sincerit 地、顏色、魔法(DFS+逆向思考)

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; }