Miquel_Fuster

Cálculo soluciones del juego de las reinas

Feb 5th, 2022 (edited)
973
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.65 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <stdlib.h>
  4.  
  5. // Número máximo de reinas con las que se va a jugar.
  6. unsigned N_MAX_REINAS = 25;
  7.  
  8. // Contendrá el array de reinas.
  9. long long *reinas;
  10.  
  11. // Libera la memoria dinámica adquirida cuando el programa se cierra
  12. void liberar() {
  13.     if(reinas != NULL)
  14.         free(reinas);
  15. }
  16.  
  17. // Comprueba que la reina fila indicada no esté amenazada por otra en la misma
  18. // vertical o en cualquiera de sus diagonales.
  19. // Devuelve true y está amenazada, false en caso contrario.
  20. bool comprobar_amenaza(long long fila_reina) {
  21.     for(long long i=0; i<fila_reina; ++i) {
  22.         if(reinas[fila_reina] == reinas[i]
  23.         || reinas[fila_reina]-fila_reina == reinas[i]-i
  24.         || reinas[fila_reina]+fila_reina == reinas[i]+i)
  25.         return true;
  26.     }
  27.     return false;
  28. }
  29.  
  30. // Imprime el tablero actual.
  31. // Marca las casillas con reina con XX, si no la hay
  32. // pone espacios.
  33. void imprimir(unsigned dimension) {
  34.     puts("");
  35.     for(unsigned i=0; i<dimension; ++i) {
  36.         for(unsigned j=0; j<dimension; ++j)
  37.             printf("---");
  38.         puts("-");
  39.         putchar('|');
  40.         for(unsigned j=0; j<dimension; ++j) {
  41.             printf("%s|", j==reinas[i]? "XX" : "  ");
  42.         }
  43.         puts("");
  44.     }
  45.     for(unsigned j=0; j<dimension; ++j)
  46.         printf("---");
  47.     puts("-\n");
  48. }
  49.  
  50. int main() {
  51.     // No hay un tablero en sí sino un array de números
  52.     // cada uno representa una reina en una fila. Dichos números
  53.     // indican la columna en que se ha posicionado la reina.
  54.     reinas = malloc((N_MAX_REINAS+1) * sizeof(long long));
  55.    
  56.     atexit(liberar);
  57.    
  58.     // Comprueba tantos tableros de dimensión x dimensión que se indiquen.
  59.     for(unsigned dimension=1; dimension<=N_MAX_REINAS; ++dimension) {
  60.  
  61.         // Número de soluciones encontradas para el tablero actual.
  62.         unsigned soluciones = 0;
  63.  
  64.         // Índice o fila de la reina a tratar.
  65.         long long i = 0;
  66.        
  67.         // Se inicializa con la reina de la fila 0 en casilla 0.
  68.         reinas[0] = 0;
  69.        
  70.         // Bucle principal del juego. En él se irán colocando todas las reinas
  71.         // y calculará las posiciones correctas para que las reinas no se ataquen.
  72.         // Se usa el backtracking para posicionar las reinas.
  73.         // El bucle se detendrá cuándo la reina de la fila 0 salga del tablero.
  74.         while(true) {
  75.             if(reinas[i] >= dimension) {
  76.                 // En caso de que la reina actual se haya posicionado fuera del tablero.
  77.                 if(i == 0)
  78.                     // En caso de ser la de la fila 0 significa que el tablero se revisó
  79.                     // completamente. Se detiene el bucle del juego para pasar al
  80.                     // sigiuente tablero.
  81.                     break;
  82.                 // No es la primera reina.
  83.                 else
  84.                     // En este caso se va a trabajar con la reina de la fila inmediatamente
  85.                     // superior y se la hace avanzar una columna para recalcular a partir
  86.                     // de esa posición.
  87.                     reinas[--i]++;
  88.             } else {
  89.                 // La reina está dentro de los límites del tablero, por tanto se mira
  90.                 // si en su posición está siendo amenazada.
  91.                 if(!comprobar_amenaza(i)) {
  92.                     // No está amenazada. Se controla si esa reina es la de la última fila.
  93.                     if(i < dimension-1)
  94.                         // No lo és, se prepara la reina de la siguiente línea para trabajar
  95.                         // con ella a partir de ahora.
  96.                         reinas[++i] = -1;
  97.                     else {
  98.                         // Es la reina de la última fila, por tanto hemos encontrado una jugada
  99.                         // tal que todas las reinas están posicionadas y ninguna está amenazada.
  100.                         // Imprimir el tablero (la salida puede ser muy larga y tal vez pueda ser
  101.                         // interesante el comentar la siguiente línea)...
  102.                         imprimir(dimension);
  103.                         // ... y actualizar el contador de soluciones
  104.                         soluciones++;
  105.                     }
  106.                 }
  107.                 // En todo caso, tanto si la reina está amenazada como si no lo está, avanzará una
  108.                 // columna para seguir comprobando el resto de posibilidades del tablero.
  109.                 reinas[i]++;
  110.             }
  111.         }
  112.         // Fin del cálculo de todas las posibilidades del tablero. Se muestra el resultado.
  113.         printf("f(%d) = %d\n\n", dimension, soluciones);
  114.     }
  115. }
  116.  
Add Comment
Please, Sign In to add comment