2010-07-09 2 views
6

Sto lavorando a un programma N Queens che consentirà all'utente di immettere una configurazione Queen come stringa. Ad esempio, quando richiesto, l'utente potrebbe immettere qualcosa come Q .... Q ..... Q..Q. che quando visualizzato come una tavola sarebbe simile:Serve aiuto con il programma N Queens (controllo delle diagonali)

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

Questo programma è semplice in quanto si presume che l'utente dovrà inserire informazioni valide. Vorrei far funzionare la parte principale del programma prima di tornare indietro e aggiungere la gestione degli errori.

Per coloro che non hanno familiarità con il puzzle delle N Queens, in pratica si hanno N Queens su una scheda N x N. Hai una regina per fila. Una scheda popolata è una soluzione se due regine non condividono la stessa riga, colonna o diagonale.

Ho implementato correttamente i controlli per righe e colonne. Tuttavia, sono perplesso su come posso controllare tutte le diagonali. So come controllare le due diagonali principali, come nel tic tac toe, ma non riesco davvero a visualizzare come posso controllare tutte le possibili diagonali?

Qualcuno può offrire aiuto?

Ecco il mio codice:

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 

Grazie Per saperne di più: bisogno di aiuto con N Programma Queens

risposta

19

Non credo che si desidera controllare tutte le diagonali, ma è possibile controllare tutte le regine invece. Puoi controllare se due regine sono sulla stessa diagonale controllando le differenze tra le righe e le colonne delle due Q. Se le differenze sono le stesse, sono sulla stessa diagonale. (In sostanza, se la pendenza della linea tra le due regine è + -1, sono sulla stessa diagonale.)

Ad esempio, supponiamo di avere due regine Q1 e Q2. Calcola il valore assoluto delle differenze nelle loro righe e colonne.

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

Se deltaRow == deltaCol, le regine sono sulla stessa diagonale.

Basta farlo per tutte le N regine.

+1

Quindi in sostanza quello che stai dicendo è che posso memorizzare il valore xey di ogni regina in un altro array 2d e quindi eseguire il controllo che hai illustrato? – Codebug

+1

@Will: Sì, è sufficiente memorizzare xey per ogni regina e fare il controllo per ogni coppia. –

+2

Non hai bisogno di un valore assoluto qui? – shinzou

1

Le diagonali possono essere espresse sotto forma di y = x + c ey = c - x. La tua tavola 4x4 avrà un totale di 10 diagonali, 5 per ogni equazione. Calcola le c (variano in base alla dimensione della scheda) e fai un ciclo su x, calcola le y.

Dovrete controllare le coordinate a meno di zero, i limiti superiori possono essere evitati semplicemente facendo in modo che la scheda sia 2x grande (in ciascuna direzione) come necessario - gli altri quadrati sono sempre vuoti, quindi il loro controllo causa nessun danno

Ho persino implementato il problema di N queens con nessuna scheda - traccia le righe, le colonne e le diagonali. All'epoca questo era più veloce perché l'addizione era molto più veloce della moltiplicazione, ma non è più così.

2

Possiamo dire che le regine sono sulla stessa diagonale se la pendenza della linea che collega le 2 regine è 1 o -1.

Let q1 e q2 tramite strutture di dati che tengono le xey posizioni di ogni regina:

xDistance = q1.x - q2.x

yDistance = q1.y - q2.y

slope = xDistance/yDistance

Così if (slope.abs() == 1) poi sono sulla stessa diagonale.

+0

Questo è un po 'pericoloso, se dividi interi potresti ottenere un 1 da 3/2. – shinzou