Solución de imanes monopolares CF1344B

Enlace de tema

Primero, consideramos las condiciones que debe cumplir un mapa legal.

  1. En cualquier fila o columna, no hay dos cuadrados negros no adyacentes A, BA, BA ,B . Porque, de acuerdo con las reglas del título, hay al menos un imán del polo sur en cada fila y columna. Entonces, no importa dónde esté el imán del polo sur, habrá al menos un imán del polo norte que pueda alcanzarA, BA, BA ,En el cuadrado blanco entre B. Por ejemplo, muestra2 22 es ilegal
  2. Para un cuadrado (x, y) (x, y)( x ,y ) , solo si(x, y) (x, y)( x ,y ) es una cuadrícula negra, o su rango (incluyendo(x, y) (x, y)( x ,y ) ) solo puede estar en(x, y) (x, y)cuando no hay una cuadrícula negra en( x ,y ) Ponle un imán del polo sur. Porque el imán del polo norte no puede ser atraído por el cuadrado blanco.

Después de confirmar que el mapa es legal, puede colocar un imán del polo sur en cada cuadrícula negra, por lo que solo necesita colocar un imán del polo norte en cada bloque de conexión negro. Entonces, la respuesta final es la cantidad de bloques negros conectados

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int Maxn=1010,inf=0x3f3f3f3f;
const int dx[]={
    
    1,-1,0,0},dy[]={
    
    0,0,-1,1};
bool vis[Maxn][Maxn],a[Maxn][Maxn];
bool r[Maxn],c[Maxn],flag[Maxn][2];
int n,m,ans;
inline bool check(int x,int y)
{
    
    
	return (x<1 || y<1 || x>n || y>m || vis[x][y] || !a[x][y]);
}
void dfs(int x,int y)
{
    
    
	vis[x][y]=1;
	for(int i=0;i<4;++i)
	{
    
    
		int u=x+dx[i],v=y+dy[i];
		if(check(u,v))continue;
		dfs(u,v);
	}
}
int main()
{
    
    
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
	{
    
    
		char s[Maxn];
		scanf("%s",s+1);
		for(int j=1;j<=m;++j)
		if(s[j]=='#')
		{
    
    
			a[i][j]=1;
			r[i]=c[j]=1;
		}
	}
	for(int i=1;i<=n;++i)
	{
    
    
		int pos=0;
		for(int j=1;j<=m;++j)
		if(a[i][j]){
    
    pos=j;break;}
		if(!pos)continue;
		for(int j=pos+2;j<=m;++j)
		if(a[i][j] && !a[i][j-1])
		{
    
    puts("-1");return 0;}
	}
	for(int j=1;j<=m;++j)
	{
    
    
		int pos=0;
		for(int i=1;i<=n;++i)
		if(a[i][j]){
    
    pos=i;break;}
		if(!pos)continue;
		for(int i=pos+2;i<=n;++i)
		if(a[i][j] && !a[i-1][j])
		{
    
    puts("-1");return 0;}
	}
	
	for(int i=1;i<=n;++i)
	for(int j=1;j<=m;++j)
	if(a[i][j] || (!r[i] && !c[j]))
	flag[i][0]=flag[j][1]=1;
	for(int i=1;i<=n;++i)
	if(!flag[i][0]){
    
    puts("-1");return 0;}
	for(int i=1;i<=m;++i)
	if(!flag[i][1]){
    
    puts("-1");return 0;}
	
	for(int i=1;i<=n;++i)
	for(int j=1;j<=m;++j)
	{
    
    
		if(vis[i][j] || !a[i][j])continue;
		dfs(i,j),++ans;
	}
	printf("%d\n",ans);
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/Brian_Pan_/article/details/107175785
Recomendado
Clasificación