2010-07-09 24 views
6

Estoy trabajando en un programa N Queens que permitirá al usuario ingresar una configuración Queen como una cadena. Por ejemplo, cuando se le solicite, el usuario puede ingresar algo como Q .... Q ..... Q..Q. que cuando se muestra como una tabla se vería así:Necesito ayuda con el programa N Queens (control de diagonales)

Q . . . 
. Q . . 
. . . Q 
. . Q . 
Is not a solution! 

Este programa es simple, ya que se supone que el usuario introducirá información válida. Me gustaría que la parte principal del programa funcione antes de volver y agregar el manejo de errores.

Para aquellos que no estén familiarizados con el rompecabezas N Queens, básicamente tiene N Queens en una placa N x N. Tienes una Reina por fila. Una placa poblada es una solución si no hay dos reinas que compartan la misma fila, columna o diagonal.

Implementé con éxito las comprobaciones de las filas y columnas. Sin embargo, estoy perplejo en cuanto a cómo puedo verificar todas las diagonales. Sé cómo revisar las dos diagonales principales, como en tic tac toe, pero realmente no puedo visualizar cómo puedo verificar todas las posibles diagonales.

¿Alguien puede ofrecer ayuda?

Aquí está mi código:

import java.util.Scanner; 
public class NQueens { 


    public static void main(String[] args) { 

     Scanner sc = new Scanner(System.in); 
     int qCount; 
     boolean solution = true; 


     System.out.println("Enter the String to test:"); 
     board = sc.nextLine(); 

     int boardLen = board.length(); 
     int maxDim = (int) Math.sqrt(boardLen); 
     char[][] gameBoard = new char[maxDim][maxDim]; 


     int counter = 0; 
     for (int i = 0; i < maxDim; i++) 
     { 
      for (int j = 0; j < maxDim; j++) 
      { 
       gameBoard[ i ][ j ] = board.charAt(counter); 
       counter++; 
      } 

     } 


     System.out.println(""); 
     System.out.println(""); 




    //check rows  

    for (int i = 0; i < maxDim; i++) 
    { 
     int queenCount = 0; 

     for (int j = 0; j < maxDim; j++) 
     { 
      if (gameBoard[ i ][ j ] == 'Q') 
      { 
       queenCount++; 


       if (queenCount > 1) 
       { 
        solution = false; 
        break; 

       } 


      } 


     } 

    } 


    // check columns 

    for (int i = 0; i < maxDim; i++) 
    { 
     int queenCount = 0; 

     for (int j = 0; j < maxDim; j++) 
     { 
      if (gameBoard[ j ][ i ] == 'Q') 
      { 
       queenCount++; 

       if (queenCount > 1) 
       { 
        solution = false; 
        break; 
       } 
      } 
     } 
    } 


    // print the board 

    for(int i = 0; i < maxDim; i++) 
    { 
     for (int j = 0; j < maxDim; j++) 
     { 
      System.out.print(gameBoard[ i ][ j ] + " "); 
     } 

     System.out.println(); 

    } 

    // print whether or not the placement of queens is a solution 
    if (solution) 
    { 
     System.out.println("Is a solution!"); 

    } 

    else 
    { 
     System.out.println("Is not a solution!"); 

    } 

    }//end main 

}//end class 

Gracias Leer más: necesito ayuda con Programa de Queens N

Respuesta

19

No creo que desea comprobar todas las diagonales, pero se puede consultar toda la reinas en cambio. Puede verificar si dos reinas están en la misma diagonal al verificar las diferencias entre las filas y columnas de las dos Q. Si las diferencias son las mismas, están en la misma diagonal. (Básicamente, si la pendiente de la línea entre las dos reinas es + -1, están en la misma diagonal).

Por ejemplo, supongamos que tiene dos reinas Q1 y Q2. Calcule el valor absoluto de las diferencias en sus filas y columnas.

deltaRow = abs(Q1 row - Q2 row) 
deltaCol = abs(Q1 col - Q2 col) 

Si deltaRow == deltaCol, las reinas están en la misma diagonal.

Simplemente hazlo para todas las reinas.

+1

Así que, básicamente, lo que dices es que puedo almacenar el valor xey de cada reina en otra matriz de 2d y luego realizar la verificación que ilustraste? – Codebug

+1

@Will: Sí, solo almacena la xey de cada reina y haz el control de cada par. –

+2

¿No necesita un valor absoluto aquí? – shinzou

1

Las diagonales se pueden expresar en forma de y = x + c o y = c - x. Su tablero 4x4 tendrá un total de 10 diagonales, 5 para cada ecuación. Calcule las c (varían según el tamaño de la pizarra) y repita x, calcule las y.

Deberá verificar las coordenadas a menos de cero, los límites superiores se pueden evitar simplemente haciendo que la tabla 2x sea tan grande (en cada dirección) como sea necesario - las otras casillas siempre están vacías, por lo que comprobarlas causa sin daño

Incluso he implementado el problema de N queens sin ninguna tabla en absoluto: rastree las filas, columnas y diagonales. En ese momento esto era más rápido porque la adición era mucho más rápida que la multiplicación, pero ese ya no es el caso.

2

Podemos decir que las reinas están en la misma diagonal si la pendiente de la línea que conecta las 2 reinas es 1 o -1.

Vamos q1 y q2 ser estructuras de datos que llevan a cabo las x e y posiciones de cada una reina:

xDistance = q1.x - q2.x

yDistance = q1.y - q2.y

slope = xDistance/yDistance

Así if (slope.abs() == 1) entonces ellos están en la misma diagonal.

+0

Esto es un poco peligroso, si divide números enteros, puede obtener un 1 de 3/2. – shinzou

Cuestiones relacionadas