Easy Finding
Time Limit:1000 MS |
|
Memory Limit:65536 K |
Total Submissions:15668 |
|
Accepted:4163 |
Description GivenM×NMatrixA.AIj ε {0, 1} (0 ≤ I <M, 0 ≤ j <N), cocould you find some rows that let every cloumn contains and only contains 1.Input There are multiple cases endedEOF. Test case up to 500.The first line of input isM,N(M≤ 16,N≤ 300). The nextMLines every line containsNIntegers separated by space.Output For each test case, if you cocould find it output "Yes, I found it", otherwise output "It is impossible" per line.Sample Input 3 30 1 00 0 11 0 04 40 0 0 11 0 0 01 1 0 10 1 0 0 Sample Output Yes, I found itIt is impossible Source POJ Monthly Contest-2009.08.23, MasterLuo |
Question:
Give you a matrix of n * m (n <= 16, m <= 300. Each element of the matrix can only be 0 or 1. Now, I ask if you can select some columns from the matrix so that none of the columns has only one.
Ideas:
Start to tease. Consider that there are only 16 questions in each row. It's fun to watch 16. This is a typical pressure. Compress each line into a binary number with a length of 16. Then the feasibility is determined. After finishing the re. This also applies. M and n are all wrong. Because there are too many values in each line, you cannot press it. Rogue. Only Baidu. I learned that it was Dancing Links, So Baidu's data. Link One.
For details, see the code:
# Include <iostream> # include <stdio. h> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 6010; int U [maxn], D [maxn], L [maxn], R [maxn], C [maxn]; // the pointer between top, bottom, and left. Column corresponding to node I in c [I. Int S [310], H [310]; // S [I] indicates the number of column 1. H [I] is the tail pointer of line I. Int n, m, cnt; void init () {int I; for (I = 1; I <= n; I ++) H [I] =-1; for (I = 0; I <= m; I ++) {S [I] = 0; L [I + 1] = I; R [I] = I + 1; U [I] = D [I] = I;} R [m] = 0; cnt = m + 1 ;} void Insert (int r, int c) {// create a chain table U [cnt] = c, D [cnt] = D [c]; // determine the upper and lower pointer information of the newly added node U [D [c] = cnt, D [c] = cnt; // restore the linked list information if (H [r] =-1) // determine the Left and Right pointer information H [r] = L [cnt] = R [cnt] = cnt; // Add the header else {L [cnt] = H [r], R [cnt] = R [H [r]; // header Insertion Method L [R [H [r] = cnt, R [H [r] = cnt;} S [c] ++; // update the Additional Information C [cnt ++] = c;} void Remov E (int c) // remove column c. {Int I, j; R [L [c] = R [c], L [R [c] = L [c]; for (I = D [c]; I! = C; I = D [I]) for (j = R [I]; j! = I; j = R [j]) D [U [j] = D [j], U [D [j] = U [j], S [C [j] --;} void Resume (int c) // restore the c column. {Int I, j; R [L [c] = L [R [c] = c; for (I = D [c]; I! = C; I = D [I]) for (j = R [I]; j! = I; j = R [j]) D [U [j] = U [D [j] = j, S [C [j] ++ ;} bool dfs () {if (R [0] = 0) return true; int I, j, c, miv = INF; for (I = R [0]; I; I = R [I]) if (S [I] <miv) miv = S [I], c = I; Remove (c ); // process column c for (I = D [c]; I! = C; I = D [I]) {for (j = R [I]; j! = I; j = R [j]) Remove (C [j]); if (dfs () return true; for (j = L [I]; j! = I; j = L [j]) Resume (C [j]);} Resume (c); return false;} int main () {int op, I, j; while (~ Scanf ("% d", & n, & m) {init (); for (I = 1; I <= n; I ++) for (j = 1; j <= m; j ++) {scanf ("% d", & op); if (op) Insert (I, j );} if (dfs () printf ("Yes, I found it \ n"); else printf ("It is impossible \ n");} return 0 ;}