# Include <iostream> # include <cstring> # include <cstdlib> # include <cstdio> // # define INPUT/** Problem: poj3740-Easy Finding Begin Time: 8: 30 p. m. 20th/Mar/2012 End Time: p. m. 21st/Mar/2012 Last Time: Maybe 4hours-; Input: Standard output: Knowledge point: DFS + backtracking + pruning State: WA x 1, TLE x 1-> AC Thought: -------------------- AC summary ---------------------- 1. defines an array selectedCol, which indicates that "1" is selected in several columns ". 2. in choos Before e, check whether selectedRow [I] is true. if it is true, this line will be selected, and continue 3. check if choose_row [I] = 1 & selectedCol [I] = 1 return false; if choose_row [I] &! SelectedCol [I] => selectedCol [I] = 1; but before choose, remember to save the selectedCol status so that you can trace back before return to false. 4. if choose fails, check whether all 1 has been found. If isFound = true is found; If isFound = true is found in recursive functions, return true; 5. if not, remember to trace back. This requires that the selectedCol State be saved in the recursive function each time, and backtracking fails. 6. if leftRow = 0, check. If check, return true; otherwise, return false; pruning policy: the recursion of each layer starts from I = 0 to rowNum. If I is selected from the upper layer, the lower layer recursion starts from I + 1. Because the upper-layer recursion is selected from 0, If I is selected, [0, I] is selected from the upper-layer recursion. In addition, the number of rows is irrelevant to the order. For example, if the first layer recursively Selects 1, then the second and third layers ...... Until the last layer of recursion, it must have traversed all the situations where 1 was selected for the first time, the first layer of recursion can select 2 and 1 2 3 4 5 6 and 6 5 4 3 2 1 is no difference, so the next layer of recursion can be added with this pruning from the ind + 1, and the next layer will pass through 653ms. A more abnormal idea: because it is 0, 1, we can represent it by bit! Then, according to the rules, it should be very fast ~ Recursive Function Definition: f (int totalRow, int totalCol, int leftRow, int ind ); totalRow indicates the total number of rows. totalCol indicates the number of columns. leftRow indicates that there are still several rows not selected. int ind indicates that the number of rows is selected from the current row. -------------------- Graffiti before the AC -------------------- in fact, this question is similar to STICK, of course, State compression is required. Compress each row into a number, and then check whether there are a few numbers that are exactly the same as 1111111... note that there can be a maximum of 10 ^ 300, so this is a relatively small! Each status is determined by whether row I is selected. After a row is selected, the column corresponding to tmp [m] is defined to be occupied. Then the rest will be converted to using the leftNum-1 row to spell out other columns. If all columns can be spelled out, return true; otherwise return false; Define the function f (rowNum, colNum, leftNum); indicates that a total of rowNum columns and colNum rows exist. The left leftNum does not select to define a check for each selection to check whether all rows in each column have been selected. Check whether the selected row conflicts with the previous row. **/Using namespace std; int matrix [20] [310]; // bool selectedCol [310]; bool selectedRow [18]; bool isFound; bool checked (const int colNum) {for (int I = 0; I <colNum; I ++) {if (! SelectedCol [I]) return false;} return true;} bool choose (const int a [310], int colNum) {int tmp_state [310]; memset (tmp_state, 0, sizeof (tmp_state); memcpy (tmp_state, selectedCol, sizeof (tmp_state); for (int I = 0; I <colNum; I ++) {if (! SelectedCol [I] & a [I]) {selectedCol [I] = a [I];} else {if (selectedCol [I] & a [I]) {memcpy (selectedCol, tmp_state, sizeof (tmp_state); return false ;}}return true ;} bool Solve (int rowNum, int colNum, int leftNum, int ind) {int tmp_state [310]; memset (tmp_state, 0, sizeof (tmp_state); if (isFound) return true; if (leftNum = 0) {if (checked (colNum) {isFound = true; return true;} else {retu Rn false ;}for (int I = ind; I <rowNum; I ++) {memcpy (tmp_state, selectedCol, sizeof (tmp_state); if (isFound) return true; if (selectedRow [I]) continue; if (choose (matrix [I], colNum) {if (selectedRow [I]! = True &&! Checked (colNum) {selectedRow [I] = true; Solve (rowNum, colNum, leftNum-1, I + 1);} else {if (checked (colNum )) {isFound = true; return true ;}// memcpy (matrix [I], tmp_state, sizeof (tmp_state); memcpy (selectedCol, tmp_state, sizeof (selectedCol )); selectedRow [I] = false;} // selectedRow [I] = false;} return false;} int main () {int n, m; # ifdef INPUT freopen ("B: \ acm \ poj3740 \ input.txt "," r ", stdin );# Endif while (scanf ("% d", & m, & n )! = EOF) {isFound = false; memset (matrix, 0, sizeof (matrix); memset (selectedCol, 0, sizeof (selectedCol); memset (selectedRow, 0, sizeof (selectedRow); for (int I = 0; I <m; I ++) {for (int j = 0; j <n; j ++) {scanf ("% d", & matrix [I] [j]) ;}} if (Solve (m, n, m, 0) {printf ("Yes, I found it \ n ");} else {printf (" It is impossible \ n ") ;}} return 0 ;}