地、颜色、魔法

链接: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;   
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值