Estaba trabajando en el problema de la Cadena de Snapper y vine a buscar una explicación sobre cómo funcionaba el algoritmo de bifurcación que encontré en las soluciones. Encontré una buena información, pero todavía me tomó un buen tiempo averiguarlo por mí mismo, siendo un novato bitwise.
Aquí está mi intento de explicar el algoritmo y cómo idearlo. Si enumeramos todos los posibles estados de encendido y apagado para cada pargo en una cadena, vemos un patrón. Dado el caso de prueba N = 3, K = 7 (3 snappers, 7 broches), mostramos la potencia y ON/OFF estados para cada pargo por cada k-ésimo encajen:
1 2 3
0b:1 1 1.1 1.0 0.0 -> ON for n=1
0b:10 2 1.0 0.1 0.0
0b:11 3 1.1 1.1 1.0 -> ON for n=1, n=2
0b:100 4 1.0 0.0 1.0
0b:101 5 1.1 1.0 1.0 -> ON for n=1
0b:110 6 1.0 0.1 0.1
0b:111 7 1.1 1.1 1.1 -> ON for n=2, n=3
La bombilla se enciende cuando todos snappers están encendidos y recibiendo potencia, o cuando tenemos un k-snap que da como resultado n 1s.Aún más simple, la bombilla está encendida cuando todos los pargos están ENCENDIDOS, ya que todos deben estar recibiendo energía para estar ENCENDIDOS (y por lo tanto, la bombilla). Esto significa que por cada K snaps, necesitamos n 1s.
Además, puede observar que k es todo 1s binarios no solo para k = 7 que satisface n = 3, sino para k = 3 que satisface n = 2 yk = 1 que satisface n = 1. Además, para n = 1 o 2 vemos que cada número de instantáneas que enciende la bombilla, los últimos n dígitos de k son siempre 1. Podemos intentar generalizar que todas las k que satisfagan n pargos sean un número binario que termina en n dígitos de 1.
podemos utilizar la expresión señalado por un cartel antes del 1 de < < n - 1 = 0b111 - 1 siempre nos n dígitos binarios de 1, o en este caso, 1 < < 3 da. Si tratamos nuestra cadena de n pargos como un número binario donde cada dígito representa encendido/apagado, y queremos n dígitos de uno, esto nos da nuestra representación.
Ahora queremos encontrar aquellos casos en los que 1 < < n - 1 es igual a algún k que termina en n dígitos binarios de 1, lo que hacemos mediante la realización de un bit a bit-y: k & (1 < < n - 1) para obtener los últimos n dígitos de k, y luego compararlo con 1 < < n - 1.
Supongo que este tipo de pensamiento es más natural después de trabajar mucho con estos tipos de problemas, pero sigue siendo intimidante para mí y dudo que alguna vez hubiera llegado a una solución de este tipo.
aquí está mi solución en Perl:
$tests = <>;
for (1..$tests) {
($n, $k) = split//, <>;
$m = 1 << $n - 1;
printf "Case #%d: %s\n", $_, (($k & $m) == $m) ? 'ON' : 'OFF';
}
para ayudar a que usted se relaciona, recuerdo '10000 - 1 = 9999', más o menos lo mismo sucede en binario – Anycorn
@aaa De hecho !. Tiene más sentido ahora. – srandpersonia
Prefiero (k^(k + 1)) >> n –