The backtracking algorithm of n queen problem can be improved by space and time trade-off further. The consideration of positions occupancy is attained by duplicate_array and two integrals. Note that these utilities can not tell all illegal moves because it is performing its job on the basis of chess_board definition. That is, power of utilities contained by chess_board are not enough to telling all illegal moves. It needs a data structure to record positions occupied by chesses. Naturally, it needs three arrays to recording row, column, diagonal1 ( upper left to lower right) and diagonal2 (upper right to lower left). Column is already represented by duplicate_array. So it needs two other array to represent diagonal1,2. Consequently, the job is how to express the meaning of one diagonal is occupied . That is, for a mo # to assign value to the corresponding element in diagonal1, 2. Assuming the one of occupied diagonal1 is diagonal1 [x] and diagonal2 is diagonal2 [y], the ass Ign Diagonal1 [x] and Diagonal2 [Y] to 1 to Denoting these Diagonals Are Occupied. An N Queen Problem HAS 2N-1 Diagonal1s and 2N-1 DiagonAl2s.
The Rules Are: (These Rules Are Obtained by Observation, IT IS CORRECT INTUIVELY (Remind The InTuitionism In Mathematics).).
Diagonal1 [J-CUR_I] = 1 IF J> = CUR_I
Diagonal1 [J-CUR_I 2 * N-1] = 1 IF J Diagonal2 [J Cur_i] = 1 The Codes: #include #include #include #include #include #include Using namespace std; Template Struct Output_functor: public unary_function { Output_functor (): n (0) {} Void Operator () (const t & p) { COUT << "(" << n << "," << p << ")" << "" N ; } Int n; } Class Chess_Board { Vector Vector Vector PUBLIC: Int n; INT CUR_I; INT NUMBER_SOLUTION; Chess_board (int Dim): N (DIM), CUR_I (0), NUMBER_SOLUTION (0) { Array.resize (n, -30000); Duplicate_Array.resize (n, 0); Diagonal1.resize (2 * n-1, 0); Diagonal2.resize (2 * n-1, 0); } Void Move (Int J) { Array [CUR_I] = J; IF (j> = cur_i) { Diagonal1 [J-CUR_I] = 1; } Else { Diagonal1 [J-CUR_I 2 * N-1] = 1; } Diagonal2 [J CUR_I] = 1; Duplicate_Array [J] = 1; } Void UN_MOVE (INT J) { Array [CUR_I] = - 30000; IF (j> = cur_i) { Diagonal1 [J-CUR_I] = 0; } Else { Diagonal1 [J-CUR_I 2 * N-1] = 0; } Diagonal2 [J Cur_i] = 0; Duplicate_Array [J] = 0; } Bool Legal_POS (INT J) { IF (duplicate_Array [J] == 0 && Diagonal2 [J Cur_i] == 0) { IF (j { IF (Diagonal1 [J-Cur_i 2 * N-1] == 0) Return True; } Else { IF (Diagonal1 [J-Cur_i] == 0) Return True; } Return False; // tricky. If LACK THIS } Else Return False; } Void write () { NUMBER_SOLUTION ; FOR_EACH (Array.begin (), Array.end (), Output_functor Cout << Endl; } } Void BackTracking (Chess_Board_delegation & C) { IF (c.get_cur_i () == C.GET_N ()) { c.write (); C.SET_CUR_I (C.GET_CUR_I () - 1); Return; } Else { For (int J = 0; j { IF (c.legal_pos (j) == false) CONTINUE; C.Move (j); C.SET_CUR_I (C.GET_CUR_I () 1); BackTracking (C); C.un_move (j); } C.SET_CUR_I (C.GET_CUR_I () - 1); } } OMITTED CHESS_BOARD_DELEGATION and Main For The Convenient of Test, IT Should Use a Template Argument To Indicate With or WithOut Output. Template Class Chess_Board { ...... Void write () { IF (with_output == true) { NUMBER_SOLUTION ; FOR_EACH (Array.begin (), Array.end (), Output_functor Cout << Endl; } Else { NUMBER_SOLUTION ; } } ...... } Template Class Chess_Board_Delegation { Chess_Board PUBLIC: Chess_Board_delegation (Chess_Board ...... } Template Void BackTracking (Chess_Board_delegation { ...... } int main () { ...... Chess_board Chess_board_delegation ...... } Using specialization can avoid the equality comparison in write function in order to improve the performance a bit The codes of definition of chess_board is: template