Skip to Content

Raab Game I

Pista 1

Primero, consideremos los empates. En un empate, nadie gana. Si a+ba+b es el número de partidas que se ganan, ¿cuántas partidas deben ser empates?

Pista 2

Después de manejar los empates, nos queda un subproblema donde el número total de cartas es k=a+bk = a+b. Como ambos jugadores tienen exactamente el mismo conjunto de cartas {1,2,,k}\{1, 2, \dots, k\}, la suma de los valores de sus cartas es igual. ¿Es posible que un jugador gane todas las rondas (es decir, marque kk) si los conjuntos son idénticos?

Pista 3

Probemos un desplazamiento cíclico. Si el Jugador 1 juega las cartas en orden creciente 1,2,,k1, 2, \dots, k, intentemos que el Jugador 2 juegue las cartas desplazadas por aa (módulo kk). Por ejemplo, si k=5k=5, el Jugador 1 podría jugar 1,2,3,4,51, 2, 3, 4, 5, y el Jugador 2 jugará 2,3,4,5,12, 3, 4, 5, 1.

Solución

Explicación

Sea NN el número de cartas y aa y bb las puntuaciones objetivo.

Primero, manejamos los empates. El número de empates necesarios es D=N(a+b)D = N - (a + b). Si D<0D < 0, el resultado es imposible porque las partidas jugadas deben sumar NN. En caso contrario, podemos satisfacer estos empates haciendo que ambos jugadores jueguen sus DD cartas más grandes una contra otra (p. ej., NN vs NN, N1N-1 vs N1N-1, etc.).

Esto reduce el problema a construir una partida con las cartas {1,2,,k}\{1, 2, \dots, k\} donde k=a+bk = a + b y no hay empates.

Condición de existencia

Debemos determinar si existe una partida válida para las kk cartas restantes.

Como kk representa las partidas que no son empate, un jugador debe ganar cada ronda. Así, que el Jugador 1 tenga una puntuación de kk implica que ganó todas y cada una de las rondas. Esto requeriría que la carta del Jugador 1 sea estrictamente mayor que la del Jugador 2 en cada enfrentamiento.

Sin embargo, ambos jugadores poseen exactamente el mismo conjunto de cartas {1,,k}\{1, \dots, k\}, así que la suma de sus cartas es igual. Si las cartas del Jugador 1 fueran estrictamente mayores en cada ronda, su suma total sería estrictamente mayor que la suma total del Jugador 2, lo cual es imposible.

Por lo tanto, si hay alguna partida que no sea empate (k>0k > 0), ningún jugador puede terminar con una puntuación de 0. Si a=0a=0 o b=0b=0, la respuesta es NO.

Construcción

Si las puntuaciones son válidas, podemos construir la partida usando un simple desplazamiento cíclico.

  1. El Jugador 1 simplemente juega todas sus cartas en orden creciente (1,2,,N1, 2, \dots, N).
  2. El Jugador 2 juega las cartas desplazadas por aa en las primeras kk rondas, y empareja al Jugador 1 en el resto.

Ejemplo: Sea k=5k=5 (cartas que no son empate), a=2a=2 y b=3b=3.

  • El Jugador 1 juega: [1,2,3,4,5][1, 2, 3, 4, 5]
  • El Jugador 2 juega: [3,4,5,1,2][3, 4, 5, 1, 2] (desplazado a la izquierda por a=2a=2)

Análisis de las primeras kk rondas:

  • En las primeras bb rondas, el Jugador 1 juega ii y el Jugador 2 juega i+ai+a. Como a>0a > 0, gana el Jugador 2 (i+a>ii+a > i). Esto le da al Jugador 2 exactamente bb puntos.
  • En las aa rondas restantes, las cartas del Jugador 2 dan la vuelta a sus valores más pequeños (1,,a1, \dots, a). El Jugador 1 juega los valores b+1b+1 hasta kk. Como b0b \ge 0, las cartas del Jugador 1 son estrictamente mayores que las del Jugador 2. Esto le da al Jugador 1 exactamente aa puntos.

Implementación

Complejidad temporal: O(N)\mathcal{O}(N)

#include <iostream> using namespace std; void solve() { int n, a, b; cin >> n >> a >> b; int draws = n - (a + b); // Imposible si necesitamos más empates que cartas disponibles if (draws < 0) { cout << "NO" << "\n"; return; } // Imposible si un jugador implica una victoria total sobre las cartas que no son empate int k = n - draws; if (k > 0 && (a == 0 || b == 0)) { cout << "NO" << "\n"; return; } cout << "YES" << "\n"; // Jugador 1: juega 1..k (rondas de ganar/perder), luego k+1..n (empates) for (int i = 1; i <= n; i++) { cout << i << " "; } cout << "\n"; // Jugador 2: desplazamiento cíclico para las primeras k cartas for (int i = 1; i <= k; i++) { // Desplazamos por a y damos la vuelta int val = i + a; if (val > k) val -= k; cout << val << " "; } // Jugador 2: empareja las cartas de empate exactamente for (int i = k + 1; i <= n; i++) { cout << i << " "; } cout << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }