/* Quiz 2. Solutions. */ // Question 1. // 8 Queens Problem. // The big observation in solving the question is that it // is enough to consider only all permutations of the numbers // 1,2, ... 8. Here is why. // No two queens can share a column. Given that there are 8 // queens and 8 coloumns on a chess board, this clearly // implies that each column must contain one, and only // one, queen. Using this first observation, we realize that // we need to keep track only of which row each queen is on. // To be more percise, let Q1 be the queen on column1, // Q2 be the queen on column2, and so on. We need only // to look at numbers which represent // which row each queen is sitting on. That is to say, // Q1 sits on column1, and row r1; Q2 sits on column2 and // row r2 and so on until Q8 sits on column8 and row r8. // // Finally, no two queens can share a row. In addition, // there are exactly 8 queens and 8 rows, so that there must // be, on each row, exactly one queen. This implies that // exactly one of numbers r1,r2,...,r8 is 1, exactly one // of them is 2, ... and so on. So is // simply some arrangement of the numbers <1,2,...,8> // // This all implies that any acceptable configuration of // queens can been written as some permutation of numbers // <1,2,...,8>. For instance, <4,5,6,7,2,1,8,3> is a configuration // saying that Q1 sits on column1, row 4; Q2 sits on column2 row 5; // Q3 sits on column3 row 6, ... until Q8 sits on column8 // row 3. Note that not all such configurations are // acceptable. // // (after all that ... ) Here is how to solve the problem // efficiently. Generate all possible permutations of // the numbers <1,2,3,...,8>. After generating each // permutation check it for validity and if it is valid // print it out. What does checking for validity mean here? // Our setup (i.e. considering only the permutation of // these numbers) already ensures that there are no // two queens sitting on the same column or row. So it // only remains to check wheather or not two // queens sit on the same diagonal. // // So, how do we check for diagonals? // There are many ways, including marking all the // diagonals in some way. Here is a simple idea: // // The diagonals on a chess board all have // slope 1 or -1. Look at small diagram below: // // BWBW-WBW Two diagonals have been marked. One // WBW-WBWB with slope -1 is marked with '*'s and // BW-WBWBW another with slope 1 is marked with '-'s // *-WBWBWB // -*BWBWBW // WB*BWBWB // BWB*BWBW // WBWB*BWB // // So, to check if queens Qi and Qj fall into the same // diagonal, we need only check to see if the slope they // make is equal to 1 or -1. That is to say, if // ri - rj = +/- (i - j) // Explanation: ri is the row where the queen on // ith column sits. Similarly, rj is the row where // the queen on the jth column sits. So the difference // between their rows is ri - rj and between their // columns is i - j. PSEUDO CODE: proc CheckTheDiagonals // given the numbers as above for any pair of (ri, rj) if ((ri - rj = i - j) or (ri - rj = -(i - j)) return false // meaning there was a conflict // We survived all the testing, so return true // meaning there was no problem. For every possible permutation P of <1,2,3,4,5,6,7,8> if (CheckTheDiagonals (P)) DisplayBoard(P) // For how to generate all possible permutations of // <1,2,3,4,5,6,7,8> very easily, check out the STL // documentation for the 'next_permutation' function. // if not, you could easily use 8 nested for-loops to // do the job for you.