Codeforces 1335F Robots en una cuadrícula

Descripción

Dé un gráfico de cuadrícula de $ n \ times m $ con color y dirección en cada ubicación. El color es blanco / negro, y la dirección indica en qué dirección se moverá el robot en esta posición hacia arriba, abajo, izquierda y derecha por una cuadrícula, y pregunta cuántos robots puedes colocar como máximo para que estos robots nunca se encuentren al caminar. Sobre la base de maximizar el número, maximice el número de robots de cuadrícula negra.

Solución

Es realmente metafísico continuar indefinidamente y ver si se puede transformar.

Debido a la red limitada, por lo que $ = $ ilimitada circulación .

Para decirlo de otra manera, primero podemos colocar cada posición en el robot y seguir caminando, eliminando se repetirá.

Obviamente, cada robot primero corre un poco y luego camina en un anillo.

Por ejemplo, si ahora tenemos dos robots, ¿cómo sabemos si se repetirán?

Primero, suponga que los dos robots no se encontraron cuando corrieron, es decir, alcanzaron su propio anillo objetivo, luego nunca se encontrarían. Esto es fácil de entender. Si no están en un ring, es obviamente imposible de encontrar; si están en un ring (por supuesto, si no están en una posición), entonces la distancia entre ellos nunca cambiará, ni se encontrarán .

Por lo tanto, la condición necesaria y suficiente para que los dos robots se encuentren es encontrarse en el camino, y después de eso, el que se ha encontrado debería haber estado caminando juntos, y el que no debería haberse encontrado nunca será tocado.

Por lo tanto, la longitud de cada carretera no debe exceder el tamaño total del mapa (es decir, $ nm $), por lo que solo debemos dejar que el robot en cada posición dé el paso $ nm $ y luego calcule la posición.

En cuanto a las estadísticas específicas, puede obtener un $ have_ {0/1, \ text {pos}} $ para indicar que el final $ \ text {pos} $ es un robot negro / blanco en esta ubicación, y luego dejar que $ tot $ indique el total, black $ representa el número total de robots negros, entonces es:

$$ \ begin {array} {l | l} 1 & \ textbf {for} i \ gets 1 \ textbf {to} nm \ textbf {do} \\ 2 & \ qquad \ textbf {if} have_ {0, i } = \ text {true} \ textbf {entonces} tot \ gets tot + 1, black \ gets black + 1 \\ 3 & \ qquad \ textbf {else if} have_ {1, i} = \ text {true} \ textbf {entonces} tot \ gets tot + 1 \\ 4 & \ qquad \ textbf {end if} \\ 5 & \ textbf {end for} \ end {array} $$

El código es solo de referencia.

#include <bits / stdc ++. h> 
usando el espacio de nombres std; 
const int NM = 1e6 + 5, LGSZ = 21; 
int n, m, nxt [LGSZ] [NM]; 
char dir [NM], col [NM], buf [NM]; 
bool tiene [2] [NM]; 
int main () 
{ 
	int t; 
	scanf ("% d", & t); 
	while (t--) 
	{ 
		scanf ("% d% d", & n, & m); 
		para (int i = 1; i <= n * m; i ++) 
			tiene [0] [i] = tiene [1] [i] = falso; 
		para (int i = 1; i <= n; i ++) 
		{ 
			scanf ("% s", buf + 1); 
			para (int j = 1; j <= m; j ++) 
				col [(i - 1) * m + j] = buf [j]; 
		} 
		para (int i = 1; i <= n; i ++) 
		{ 
			scanf ("% s", buf + 1);
		} 
		para (int i = 1; i <= n * m; i ++) 
			switch (dir [i]) 
			{ 
				case 'U': nxt [0] [i] = i - m; rotura; 
				caso 'D': nxt [0] [i] = i + m; rotura; 
				caso 'L': nxt [0] [i] = i - 1; rotura; 
				caso 'R': nxt [0] [i] = i + 1; rotura; 
			} 
		para (int i = 1; i <LGSZ; i ++) 
			para (int j = 1; j <= n * m; j ++) 
				nxt [i] [j] = nxt [i - 1] [nxt [i - 1 ] [j]]; 
		para (int i = 1; i <= n * m; i ++) 
		{ 
			int pos = i; 
			para (int j = LGSZ - 1; ~ j; j--) 
				if (n * m >> j & 1) pos = nxt [j] [pos]; 
			tener [col [i] ^ 48] [pos] = verdadero; 
		} 
		{ 
		int negro = 0, tot = 0;
		para (int i = 1; i <= n * m; i ++)
			if (tener [0] [i]) tot ++, negro ++; 
			de lo contrario if (have [1] [i]) tot ++; 
		} 
		printf ("% d% d \ n", tot, negro); 
	} 
	devuelve 0; 
}

Supongo que te gusta

Origin www.cnblogs.com/syksykCCC/p/1335F.html
Recomendado
Clasificación