ICPC North Central NA Contest 2017 G.Sheba's Amoebas

G.Sheba’s Amoebas

计蒜客重现赛题目链接-G.Sheba’s Amoebas

After a successful Kickstarter campaign, Sheba Arriba has raised enough money for her mail-order biology supply company. “Sheba’s Amoebas” can ship Petri dishes already populated with a colony of those tiny one-celled organisms. However, Sheba needs to be able to verify the number of amoebas her company sends out. For each dish she has a black-and-white image that has been pre-processed to show each amoeba as a simple closed loop of black pixels. (A loop is a minimal set of black pixels in which each pixel is adjacent to exactly two other pixels in the set; adjacent means sharing an edge or corner of a pixel.) All black pixels in the image belong to some loop.

Sheba would like you to write a program that counts the closed loops in a rectangular array of black and white pixels. No two closed loops in the image touch or overlap. One particularly nasty species of cannibalistic amoeba is known to surround and engulf its neighbors; consequently there may be amoebas within amoebas. For instance, each of the images in figure below contains four amoebas.
在这里插入图片描述
The first line of input contains two integers mm and nn, (1≤m,n≤100)(1≤m,n≤100). This is followed by mm lines, each containing nn characters. A ‘#’ denotes a black pixel, a ‘.’ denotes a white pixel. For every black pixel, exactly two of its eight neighbors are also black.

Display a single integer representing the number of loops in the input.

输出时每行末尾的多余空格,不影响答案正确性

样例输入1

12 12
.##########.
#..........#
#..#...##..#
#.##..#..#.#
#......#.#.#
#....#..#..#
#...#.#....#
#..#...#...#
.#..#.#....#
#....#.....#
#.........#.
.#########..

样例输出1

4

样例输入2

12 10
.#####....
#.....#...
#..#..#...
#.#.#.#...
#..#..#...
.#...#....
..###.....
......#...
.##..#.#..
#..#..#...
.##.......
..........

样例输出2

4

题目大意

给出一个m×n的方格棋盘,定义在某#格周围的八个方格内至少有两个#,那么他们同属一个连通块,求连通块的个数

解题思路

DFS/BFS,棋盘搜索入门题
其实就是找该图中有几个环,(“##”这种不算环),dfs求连通块个数即可

  • 至于怎么判环,给每个‘#’用def数组标上dfs序即可,即每次搜索时每找到一个#就++cnt,最后如果能回到def[x][y]=1即表示形成一个环
  • 用一个vis数组标记搜索过的点,以免重复记录,当然也可以不应vis数组,每次搜索后将棋盘中的‘#’置为‘ . ’即可
  • for循环每次搜索前记得将cnt置为0
  • 其他就都是dfs的板子,具体操作见代码

附上代码

#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(-x))
using namespace std;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=1e5+5;
typedef long long ll;
typedef pair<int,int> PII;
int dx[]={0,0,-1,-1,-1,1,1,1};
int dy[]={1,-1,0,1,-1,0,-1,1};
int m,n;
char maze[110][110];
bool vis[110][110];
int def[110][110],ans,cnt;
void dfs(int x,int y){
	def[x][y]=++cnt;
	for(int i=0;i<8;i++){//分别向八个方向搜索
		int tx=x+dx[i];
		int ty=y+dy[i];
		if(def[tx][ty]==1)//判环
			ans++;
		if(maze[tx][ty]=='#'&&!vis[tx][ty]&&tx>=1&&tx<=m&&ty>=1&&ty<=n){
			vis[tx][ty]=1;
			dfs(tx,ty);
		}	
	}
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	cin>>m>>n;
	for(int i=1;i<=m;i++)
		cin>>maze[i]+1;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			cnt=0;
			if(maze[i][j]=='#'&&!vis[i][j])
				dfs(i,j);
		}
	}
	cout<<ans<<endl;
	return 0;
}

发布了88 篇原创文章 · 获赞 9 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Fiveneves/article/details/104623855