// Little Bishops (the image on the board) // PC/Ultraviolet IDs: 110801/861, popularity: C, success rate: high level: 2 // verdict: accepted // submission date: 2011-06-19 // ultraviolet A run time: 0.024 S /// copyright (c) 2011, Qiu. Metaphysis # Yeah dot net // how many pictures can be placed on the N * n board without conflict with each other? This is my consideration, because the elephant eats the child in the form of a // diagonal line. Then, after an elephant is placed on the board, it occupies either a diagonal line or two. Of course, first place the image // occupies a diagonal line. You can maximize the number of objects to be placed, and place one image on the diagonal lines of the main and secondary components of the Board, then, the total number of items is 2. In this way, the main and secondary diagonal lines divide the Board areas into four equivalent areas, no matter where/where they are placed, because the symmetry of the Board produces the same effect, only the placement method of one area is considered, and then the total placement number is obtained through symmetry. Assume that an 8*8 chessboard has an image on each of the Primary and Secondary diagonal lines. The occupied position is represented by the asterisk, the unoccupied position is represented by an uppercase letter "O. /// 1 2 3 4 5 6 7 8 // 1 B O-O-O-O-O-O B // 2 O * O-O-O-O * o // 3 O # O * O-O * O & O // 4 O # O ** O & O/5 o # O ** O & O/6 O # O * O + O * o & O // 7 O * O + O * o // 8 * O + O * // As shown in, there is a symbolic connection that does not occupy the position and the + symbolic connection does not occupy the position, the coordinates (1, 1) and // the coordinates (8, 1) have placed the image. First, consider-the region where the symbol is connected. In this region, any position is selected for placement. // The image occupies two diagonal lines (non-primary and secondary diagonal lines), and any image is placed in this region, it will surely lead to the occupying of the left and right sides of the areas where you can/put the image, but not the places where you can place the image (that is, the areas with the # symbol and the & symbol ), then, the number of objects that can be placed in the-symbol zone/field is determined by the number of intersections in the diagonal line, that is, a maximum of six images can be placed without mutual conflict. The total number of images that can be placed is 8, and the Board status changes to the following: /// 1 2 3 4 5 6 7 8 // 1 B/2 ******** // 3 *** */4 */5 */6 * O + O ***/ /7 ** O + O ** // 8 * O + O * // The + Region for example, similarly Six images can be placed without conflict. The maximum number of pictures that can be placed on the 8*8 board is 14. /// 1 2 3 4 5 6 7 8 // 1 B/2 ******** // 3 *** * *****/4 *********/5 **********/6 ********// 7 */8 * B * // The following is a summary, the maximum number of pictures that can be placed on the N * n board is n + (n-2), that is, 2 * (N-1) // number of pictures, N> = 2. For a 1*1 board, only one image can be placed. Can I solve this question through a combination? The answer is yes. The chess board is generally divided into white and black areas. In the white area, it is like an image that cannot attack the black area. It rotates the black and white checker 45 degrees clockwise, then the main and sub-diagonal lines in the original form become vertical and horizontal. At this time, the method of walking is the same as that of the car, the problem is how many ways to place K cars on the N * n board such. Assume that the number of grids in line I of the board is R [I], // use t [I] [J] to indicate that J cars are not in conflict with each other in the previous line, the following recursive relationship is obtained: /// T [I] [J] = T [I-1] [J] + T [I-1] [J-1] * (R [I]- (J-1 )) /// the boundary condition is: // T [I] [0] = 1, 0 <= I <= N/T [0] [J] = 0, 1 <= j <= K // The meaning of the recursive relationship can be understood as follows: because only one car can be placed in each row, J cars are either in the first line I-1, // or there is a car in the first line I, the method for placing all J vehicles in the first I-1 line is t [I-1] [J], row I is placed // a car, place J-1 car in the first line of I-1, the first line of I-1 occupies the J-1 grid when the J-1 car is placed, and the remaining number of grids is R [I]- (J-1), then according to the multiplication principle, the second // placement method is the product of the two, and according to the addition principle, the total placement method is the sum of the first and second methods. The boundary // situation is also easy to understand. There are one method for placing 0 cars in the first line, and one method for placing J cars in the first 0 rows. // Because the board is divided into two areas, the total number of places calculated at the end should be the accumulation of the two areas. //// How can we solve this problem through Backtracking Based on the eight queens problem? Through observation and analysis, we can know that the methods for constructing candidate sets are key differences. The eight queens problem is in building candidate sets, because the queen cannot be placed in the same row and the same // column, the space for searching can be reduced. However, when an image is placed in the same row or in the same column, therefore, the number of searches increases. // However, when there are few boards, the search can still be completed. When the board is further increased, the Backtracking Method becomes difficult, you need to use the // composite mathematical method to calculate the number of placement schemes. When representing the position of the image on the board, different representation methods are required because it can be in the same row or in the same column, from 1-N ^ 2. ///// * The process of building a candidate set for the eight queens problem. * // Construct_candidates (int A [], int K, int N, int C [], int * ncandidates) // {// int I, J; // bool legal_move; // * ncandidates = 0; // for (I = 1; I <= N; I ++) // {// legal_move = true; /// * For objects to be placed, consider each position except the diagonal line of the existing object, because the limit * // * is not saved, only one such restriction condition can be placed for one row or column when the Queen is placed. * /// For (j = 1; j <K; j ++) // {// If (ABS (k)-j) = ABS (I-A [J]) // legal_move = false; // * for placement objects, it is not necessary to detect threats from rows or columns, you only need to check * /// * for threats on the diagonal line. * // If (I = A [J]) // legal_move = false; //} // If (legal_move = true) // {// C [* ncandidates] = I; // * ncandidates = * ncandidates + 1; /// // for the process of building candidate sets, although the threats from rows or columns do not need to be considered, however, you need to consider each position except the diagonal line, and there is no restriction that only one row can be put on one image. This is the reason for the increase in search time. If you do not consider the position number when placing the image, a duplicate placement scheme will be generated, this can be avoided by selecting a position with a sequence number greater than the position number of the selected image each time. Despite the corresponding pruning measures, it is still easy to get the Tle for the larger N and K. It is advantageous to use a combination of methods to solve the problem, unless the backtracking method is used to generate all the solutions in a given range, and then fill in the table according to the specific N and K output, otherwise, when N and K increase further, the calculation time will be long. //// The query results of the WordPress 10237 bishops are similar to those of this question. However, N and K are large enough to search back, it is required to use the combination method and big number calculation. # Include <iostream> # include <algorithm> using namespace STD; # define maxn 8 long solution_count; void construct_candidates (INT bishops [], int C, int N, int candidates [], int * ncandidates) {bool legal_move; // tag of valid placement. // For objects to be placed, you need to consider each location, because there is no situation where only one row can be placed as a queen. Only positions larger than the current image are considered to avoid repeated solution generation. Because the number of the image in the last position is greater than the number of the image in the previous position, you can start searching for the position where the image with the largest number can be placed, this reduces the search volume. Int start = 0; If (c) Start = bishops [C-1]; * ncandidates = 0; For (int p = start; P <n * n; P ++) {legal_move = true; // the diagonal line of the placed image cannot be placed. Check the diagonal lines of the placed image. // Exit the loop as soon as possible if the conditions are not met. For (Int J = 0; j <C; j ++) if (ABS (Bishops [J]/n-P/N) = ABS (Bishops [J] % N-P % N) {legal_move = false; break;} // if the position is valid, add it to the candidate set. If (legal_move = true) candidates [(* ncandidates) ++] = P ;}// trace back to find all possible solutions. Void backtracking (INT bishops [], int C, int N, int K) {If (C = k) solution_count ++; else {int ncandidates; int candidates [maxn * maxn]; // construct a candidate set. Construct_candidates (bishops, C, N, candidates, & ncandidates); For (INT I = 0; I <ncandidates; I ++) {bishops [c] = candidates [I]; backtracking (bishops, C + 1, n, k) ;}} long little_bishops_by_backtracking (int n, int K) {int bishops [2 * (maxn-1) + 1]; solution_count = 0; backtracking (bishops, 0, n, k); Return solution_count;} Long little_bishops_by_combinatorics (int n, int K) {// assume that the first grid in the upper left corner of the checker is a white grid.. Long long white [9]; long black [9]; // obtain the number of white grids in each column. The number of cells is arranged in ascending order. For (INT I = 1; I <= N; I ++) White [I] = (I % 2 )? I: white [I-1]); // obtain the number of black grids in each column. The number of cells is arranged in ascending order. For (INT I = 1; I <= n-1; I ++) Black [I] = (I % 2 )? (I + 1): black [I-1]); // Method for placing J images in the I column before storage. The number of placement methods for the white and black grids is calculated respectively. // Given a chessboard with a maximum of 8x8, the maximum number of objects to be placed is 14. Long long white_solutions [9] [15] = {0}; long black_solutions [9] [15] = {0}; // initialize the boundary condition. For (INT I = 0; I <= N; I ++) white_solutions [I] [0] = 1; for (Int J = 1; j <= K; j ++) white_solutions [0] [J] = 0; // calculate the number of white lattice placement schemes based on the recursive formula. For (INT I = 1; I <= N; I ++) for (Int J = 1; j <= K & J <= I; j ++) white_solutions [I] [J] = white_solutions [I-1] [J] + white_solutions [I-1] [J-1] * (white [I]-J + 1); // initialize the boundary condition. For (INT I = 0; I <= n-1; I ++) black_solutions [I] [0] = 1; for (Int J = 1; j <= K; j ++) black_solutions [0] [J] = 0; // calculate the number of black lattice placement schemes based on the recursive formula. For (INT I = 1; I <= n-1; I ++) for (Int J = 1; j <= K & J <= I; j ++) black_solutions [I] [J] = black_solutions [I-1] [J] + black_solutions [I-1] [J-1] * (black [I]-J + 1); // count the total number of Placement Solutions. According to the multiplication principle and addition principle, the total number of solutions is equal to N * n. The number of solutions where n rows of white grids are placed with 0 images multiplied by the number of solutions where n-1 rows of black grids are placed with K images, // Add n rows of white grids to put one image. Multiply the n-1 rows of black grids to put k-1 images, add n rows of white grids to put 2 images multiplied by N-1 rows of black grids to put // set the number of K-2 images ...... long long Total = 0; For (INT I = 0; I <= K; I ++) total + = white_solutions [N] [I] * black_solutions [n-1] [k-I]; return total;} Long little_bishops (INT N, int K) {// handling solutions in special cases. // K = 0, that is, there is only one way to do this without placing an image on the board. If (k = 0) return 1ll; // when the chessboard is 1*1, only one image can be placed. If (n = 1) return K; // when n> = 2, the analysis shows that at most 2 * (N-1) images can be placed. // No solution is available when the value is greater than 2*(N-1. If (k> 2 * (N-1) return 0ll; // general solution. // Return little_bishops_by_backtracking (n, k); Return little_bishops_by_combinatorics (n, k);} int main (int ac, char * AV []) {int N, K; while (CIN> N> k, n | K) cout <little_bishops (n, k) <Endl; return 0 ;}