// N queens Problem
// Test-backtracking algorithm and Recursive Implementation
// Sum is used to record the number of different la s that have been successfully placed by the Queen; upperlim is used to mark that all columns have been placed by the Queen.
Long sum = 0, upperlim = 1;
// Test the algorithm from the rightmost column.
Void test (long row, long lD, long rd ).
{
If (row! = Upperlim)
{
// Perform the "or" operation on Row, LD, and RD to obtain all columns that can be placed in the Queen's position. The corresponding bits are 0,
// Then retrieve the full number of "and" on the backend to obtain all the positions where the current Queen can be placed. The corresponding column is changed to 1.
// Determine which columns can be placed as the Queen.
Long Pos = upperlim &~ (Row | LD | rd );
While (POS) // 0 -- there is no place for the Queen to go back.
{
// Copy the bits whose rightmost side is 1, and set the remaining bits to 0.
// Obtain the rightmost column of the Queen.
Long P = POS &-Pos;
// Clear the bits whose rightmost position is 1.
// This is used to obtain the rightmost available columns for the next time,
// The program will go back to this position to continue testing.
Pos-= P;
// Row + P: set the current column to 1, indicating to record the column placed by the Queen.
// (LD + p) <1, marking the adjacent columns on the left of the current queen cannot be placed by the next queen.
// (LD + p)> 1. The column adjacent to the right of the current queen cannot be placed by the next queen.
// The shift operation here is actually the limit on the diagonal line of the record, just because the problems are all
// Solve the problem in a row grid, so the column restriction is acceptable. Obviously, with the shift
// Before each selection column, an existing queen in the n × n mesh is directed at its diagonal line.
// All restrictions are recorded.
Test (row + P, (LD + p) <1, (RD + p)> 1 );
}
}
Else
{
// All the bits of row are 1, that is, a successful layout is found and Backtracking is performed.
Sum ++;
}
}
Int main (INT argc, char * argv [])
{
Time_t TM;
Int n = 16;
If (argc! = 1)
N = atoi (argv [1]);
TM = time (0 );
// The maximum integer value is 32 bits,
// If you want to solve the Queen Problem with N greater than 32, you need
// Use the bitset data structure for storage.
If (n <1) | (n> 32 ))
{
Printf ("can only calculate between 1-32/N ");
Exit (-1 );
}
Printf ("% d /N", N );
// N queens only need to be stored in N bits. If a column in N has a queen, the corresponding bit is set to 1.
Upperlim = (upperlim <n)-1;
Test (0, 0, 0 );
Printf ("% LD in total, calculation time % d seconds/N", sum, (INT) (time (0)-TM ));
}
The above code is easy to understand, but I think the core is the design of the data structure used by the test-backtracing algorithm.
The program uses recursion, that is, the automatic tracing function provided by the compilation system.
The core of the algorithm: The Bit Array is used instead of the Int or bool array to store the occupied or available information of the current grid.
It can be seen that N queens need n-bit representation.
Clever: In the past, we had to move the Queen in an N * n square mesh to perform TEST backtracking. We had to observe every step.
And record the information of the grids on the left and right sides of a grid. If bit is used for information storage, you can only
That is, you can perform a test backtracing in a grid (one row × n columns). The limitations on the diagonal lines are categorized as column restrictions.
The program mainly needs the following three bit arrays, each corresponding to a column of the grid, in C is to take a certain part of the integer continuous bit.
.
Row is used to record which columns are currently unavailable, that is, which columns are occupied by the queen, corresponding to 1.
LD, Rd also records which columns are currently unavailable, but does not indicate that the columns are occupied by the queen. Instead, it indicates that the current Queen is located on the diagonal line.
The position of the log. After the "or" operation is performed on these three-digit groups, it indicates the locations where new queens can be placed, corresponding to 0.
The location of the new queen. As shown in figure 8. The first step is to solve the Queen's problem:
Row: [] [] [] [] [] [] [] [] [*]
Ld: [] [] [] [] [] [] [*] []
RD: [] [] [] [] [] [] [] [] []
--------------------------------------
Row | LD | RD: [] [] [] [] [] [] [*] [*]
The testing process for all the next locations is implemented through bitwise operations, which borrow the advantages of the C language. For details, see the code comments.
Considering the symmetry of the N × n board, this algorithm can greatly improve the efficiency of N!