Juego hud 1846 Bash (solución simple o solución Sprague-Grundy)

¿Cuál es el primer juego que eres lo suficientemente valiente para jugar? Muy simple, se define de la siguiente manera:
1. Este juego es para dos jugadores;
2. Hay n piedras en una pila;
3. Dos personas se turnan;
4. Cada paso puede quitar 1...m de piedras. 5.
Gana el bando que tome todas las piedras primero;

Si ambos jugadores en el juego están usando la estrategia óptima, indique cuál puede ganar.

Entrada
Los datos de entrada primero contienen un número entero positivo C (C <= 100), lo que indica que hay C conjuntos de datos de prueba.
Cada conjunto de datos de prueba ocupa una línea y contiene dos números enteros n y m (1 <= n, m <= 1000). Los significados de n y m se describen en el título.

Salida
Si la persona que va primero gana, envíe "primero"; de lo contrario, envíe "segundo" y la salida de cada instancia ocupa una línea.

Entrada de muestra
2
23 2
4 3
ideas:

1. Cuando n <= m, el primer jugador puede tomar directamente al primer jugador para ganar.

2. Cuando n = m+1, el primer jugador debe perder.

using namespace std;

int main()
{
    int T,n,m;
    cin>>T;
    while(T--){
        cin>>n>>m;  
        if(n %(m-1) == 0) printf("second\n");
        else  printf("first\n");
    }
}

Solución con juego de gráficas y función Sprague-Grundy:

La regla del juego de gráficos es estipular un gráfico acíclico dirigido, colocar una pieza de ajedrez en un punto de partida y dos jugadores mueven alternativamente la pieza de ajedrez a lo largo del borde dirigido, y el jugador que no puede moverse será considerado perdedor.

   x representa el número de piedras, cuando el número de piedras es 0, la primera mano es un estado de derrota (la primera mano se refiere a la persona que actualmente está tomando la piedra) y el ida y vuelta es recursivo.

#define _CRT_SECURE_NO_WARNINGS 1	
#include<iostream>
using namespace std;
const int MAX = 1001;
int n, m, sg[MAX], s[MAX];
void getSG() {
	memset(sg, 0, sizeof(sg));
	for (int i = 1; i <= n; i++) {
		memset(s, 0, sizeof(s));
		for (int j = 1; j <= m && i - j >= 0; j++) {
			s[sg[i - j]] = 1;
		}
		for (int j = 0; j <= n; j++) {
			if (!s[j]) {
				sg[i] = j;
				break;
			}
		}
	}
}
int main() {
	int c;
	cin >> c;
	while (c--) {
		cin >> n >> m;
		getSG();
		if (sg[n]) cout << "first" << endl;
		else cout << "second" << endl;
	}
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/zhi6fui/article/details/128706050
Recomendado
Clasificación