D. Monopole Magnets(DFS&构造)

D. Monopole Magnets(DFS&构造)

题目传送门

思路:

p o s 1 : pos1: 当一行全为白时,显然这一行 N N 极到不了,因为每一行都必须有一个 S S 极。假设这个 S S 极对应的列存在黑色,显然 N N 极要向该 S S 极靠近,但 N N 极又到不了白色,所以显然这样是无解的,所以存在全白行必须对应全白列.

p o s 2 : pos2: 当一行存在黑色时,黑色必须是连续的一部分,否则该行的 S S 极会吸引 N N 极越过白色部分到黑色的一端去.对列同理.

其他情况都可以通过在黑色连通块放一个 N N 极然后每格都放一个 S S 极构造出来。最后答案就是 D F S DFS 的次数了。

时间复杂度: O ( n m ) O(nm)

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
char mp[N][N];
int n,m,f1,f2,ans,d[4][2]={0,1,0,-1,1,0,-1,0};
void dfs(int x,int y){ //dfs黑色连通块. 
	mp[x][y]='.';
	for(int i=0,nx,ny;i<4;i++){
		nx=x+d[i][0],ny=y+d[i][1];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mp[nx][ny]=='#')
			dfs(nx,ny);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%s",mp[i]+1);
	for(int i=1;i<=n;i++){
		int c=0;
		for(int j=1;j<=m;j++)
			if(mp[i][j]=='#')
				if(!c||mp[i][j-1]=='.') c++;
		if(c>1) return puts("-1"),0;//特判黑色部分.行同理. 
		if(!c) f1=1;
	}
	for(int j=1;j<=m;j++){
		int c=0;
		for(int i=1;i<=n;i++)
			if(mp[i][j]=='#')
				if(!c||mp[i-1][j]=='.') c++;
		if(c>1) return puts("-1"),0;
		if(!c) f2=1;
	}
	if(f1+f2==1) return puts("-1"),0;//特判全白行,全白列. 
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(mp[i][j]=='#') dfs(i,j),ans++;
	printf("%d\n",ans);
	return 0;
}
原创文章 201 获赞 165 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/105969917
今日推荐