Codeforces1344B - Monopole Magnets(dfs求连通块)

题目链接:

  https://codeforces.ml/problemset/problem/1344/B

解题思路:

  啊啊啊啊啊!!!打CF时想的正解被自己傻X的否定掉了…
  首先,同一行或者同一列,只能有连续的一段,如果有多段,则必然不行
  因为南极是每一行以及每一列都要有,假设a和b为同一行上不相邻的两个#,那么该行的南极无论放哪都可能会使北极到白格上
  如果有一行全为空白格,全部列都至少有一个#,那么该行的南极无论放哪,都不符合题意(列反过来即可)
  最后,答案即为连通块的个数,因为北极只能在本身所在的连通块移动,所以为了最少,肯定每个连通块只有一个啦!!!

AC代码:

#include<bits/stdc++.h>
using namespace std;
char Map[1010][1010];
int vis[1010][1010];//vis[i][j]代表这是哪个连通块(#相连的)
int row[1010],column[1010];
int n,m,flag=1;
void dfs(int x,int y,int cnt) {
	if(x<1||x>n||y<1||y>m||vis[x][y]||Map[x][y]=='.') return;
	vis[x][y]=cnt;
	dfs(x+1,y,cnt);
	dfs(x-1,y,cnt);
	dfs(x,y+1,cnt);
	dfs(x,y-1,cnt);
	return;
}
int main() {
	int cnt=0;
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++)
		scanf("%s",Map[i]+1);
	//先计算出每一行以及每一列有多少段连续的
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			if(Map[i][j]=='#'&&Map[i][j-1]!='#')
				row[i]++;
	for(int j=1; j<=m; j++)
		for(int i=1; i<=n; i++)
			if(Map[i][j]=='#'&&Map[i-1][j]!='#')
				column[j]++;
	int num1=0,num2=0;
	for(int i=1; i<=n; i++)
		if(row[i]>1) flag=0;//如果出现一行或者一列内有多段连续的那么则不成立
		else if(!row[i]) num1++;//计算有多少行空白的
	for(int i=1; i<=m; i++)
	    if(column[i]>1) flag=0;
	    else if(!column[i]) num2++;//计算有多少列空白的
	if(!flag||num1>0&&num2==0||num1==0&&num2>0) {
	    //ps:注意是有一行为空白的,不是只有一行
		printf("-1\n");
		return 0;
	}
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			if(Map[i][j]=='#'&&vis[i][j]==0)
				dfs(i,j,++cnt);
	printf("%d\n",cnt);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值