1. 程式人生 > >地、顏色、魔法

地、顏色、魔法

連結:https://ac.nowcoder.com/acm/contest/218/A
來源:牛客網
牛客練習賽11.16

   現在,你作為一名新星鵬洛客,找到了一塊絕佳的修煉地。這塊地方可以被描述成一個 n x m 的矩形。你已經在這塊地中的一些位置打好了標記。接下去,就該對整塊地賦予你的顏色了。一個位置能被賦予你的顏色,當且僅當滿足以下條件之一:
       1. 這個位置被打上了標記。
       2. 這個位置在不經過被打標記的位置的情況下與邊界不連通(這個圖是四聯通的)。換句話說,如果你從這個位置開始,在不經過被打標記的位置,且只能向上下左右四個方向移動的情況下永遠不能走到地圖的邊界,那麼這個位置符合條件。
       現在,你的好基友想知道,你能為多少個位置賦予你自己的顏色呢?

輸入描述:

第一行包含兩個正整數 n, m ,表示地圖的長和寬。
接下去 n 行,每行一個長為 m 的字串,表示地圖的一行。
其中  表示該位置未被打標記; 表示該位置被打了標記。
保證地圖僅由  和  構成。

輸出描述:

輸出僅一行,包含一個整數,表示你的答案。

 

示例1

輸入

複製

4 4
....
.###
.#.#
.###

輸出

複製

9

說明

 

可以被賦予顏色的位置在下圖中用  標出了。

\texttt{....}
\texttt{.@@@}
\texttt{.@@@}
\texttt{.@@@}

備註:

1 ≤ n x m ≤ 106

-----------------------------------

題意就是上面內個(不好懂是吧) hh

題意大概就是讓你把一塊不與外面聯通的區域(這塊區域被‘#’包圍)或“#”格塗色,問塗得塊數個數

如果從正面考慮的話得從這塊不與外面聯通的區域裡的‘.’開始搜 ,判斷是否與外面聯通,但其實可以直接從圖四周邊界搜不是“#”的塊比如‘ . ’和 被‘ # ’包圍的‘.’聯通區域(因為被被‘ # ’包圍的‘.’不會被搜到(自己想一下))標記成其他字元 如 @,最後在跑一邊圖把不是@的塊數累加即為結果。

-------->注意得用vector存圖 ,陣列不夠(我就是不會vector存圖,沒做出來....今天才學的vector存圖,補的題)

程式碼如下:

#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<vector> 
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
vector<char>e[maxn];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int n,m;
bool judge(int x,int y){
	if(x<0||x>=n||y<0||y>=m||e[x][y]=='#'||e[x][y]=='@')
	   return false;
	return true;   
}
void dfs(int x,int y){	
	e[x][y]='@';
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(judge(nx,ny)){
			dfs(nx,ny);
		}
	}	
}
int main(){
	scanf("%d%d",&n,&m);
	char x;
	for(int i=0;i<n;i++){
		getchar();
	  for(int j=0;j<m;j++){
	  	scanf("%c",&x);
	  	e[i].push_back(x);
	  }
   }
   	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(i==0||i==n-1){
				if(e[i][j]=='.'){
					dfs(i,j);	
				}
			}
			if((j==0&&i!=0)||(j==0&&i!=n-1)||(j==m-1&&i!=0)||(j==m-1&&i!=n-1)){
				if(e[i][j]=='.'){
					dfs(i,j);	
			}	
		}
	}
}

	  int ans=0;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(e[i][j]!='@'){
				ans++;
			}
		}
	}
	cout<<ans<<endl;   
	return 0;	
}
 

自己的一個特別智障的地方

bool judge(int x,int y){
	if(x<0||x>=n||y<0||y>=m||e[x][y]=='#'||e[x][y]=='@')
	   return false;
	return true;   
}

判斷是否能往下搜的條件,我是從反面考慮的,剛開始沒注意到(沒這個條件e[x][y]=='@')當經過某點“ . ”改為‘ @ ’後,其他點搜是再經過此點是會一直搜,死遞迴...

如果不考慮那麼多的話 直接 :

bool judge(int x,int y){
	if(x>=0&&x<n&&y>=0&&y<m&&e[x][y]=='.')
	   return true;
	return false;   
}