题目链接:http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3155
题意:给出一张图有灯泡的连接关系和初始灯泡状态,相邻的灯泡如果相连则可以相互影响,求使所有灯泡最后都关闭的不同操作的情况数。
和poj1222差不多,不过这题求的是方案数。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define maxn 12 4 int a[maxn*maxn][maxn*maxn]; 5 char mp[maxn*2][maxn*2]; 6 int n, m; 7 int Gauss(int n, int m) 8 { 9 int r, c; 10 for(r = 0, c = 0; r < n && c < m; r++, c++) 11 { 12 int max_r = r; 13 for(int i = r+1; i < n; i++) 14 { 15 if(fabs(a[i][c]) > fabs(a[max_r][c])) max_r = i; 16 } 17 if(a[max_r][c] == 0){r--; continue;} 18 if(max_r != r) 19 { 20 for(int i = r; i < m+1; i++) swap(a[r][i], a[max_r][i]); 21 } 22 23 for(int i = r+1; i < n; i++) 24 { 25 if(a[i][c] == 0) continue; 26 for(int j = r; j < m+1; j++) 27 { 28 a[i][j] ^= a[r][j]; 29 } 30 } 31 } 32 33 for(int i = r; i < n; i++) 34 { 35 if(a[i][c]) return -1; 36 } 37 if(r < m) return m-r; 38 else return 0; 39 } 40 int main() 41 { 42 //freopen("in.txt", "r", stdin); 43 while(~scanf("%d%d", &n, &m)) 44 { 45 getchar(); 46 for(int i = 0; i < 2*n-1; i++) 47 { 48 string s; 49 getline(cin, s); 50 for(int j = 0; j < 2*m-1; j++) mp[i][j] = s[j]; 51 } 52 memset(a, 0, sizeof(a)); 53 int N = n*m; 54 for(int i = 0; i < N; i++) a[i][i] = 1; 55 56 for(int i = 0; i < 2*n-1; i++) 57 { 58 for(int j = 0; j < 2*m-1; j++) 59 { 60 if(i%2) 61 { 62 if(mp[i][j] == '|') a[(i-1)/2*m+j/2][(i+1)/2*m+j/2] = a[(i+1)/2*m+j/2][(i-1)/2*m+j/2] = 1; 63 } 64 else 65 { 66 if(j%2) 67 { 68 if(mp[i][j] == '-') a[i/2*m+(j-1)/2][i/2*m+(j+1)/2] = a[i/2*m+(j+1)/2][i/2*m+(j-1)/2] = 1; 69 } 70 else 71 { 72 if(mp[i][j] == 'o') a[(i/2)*m+j/2][N] = 1; 73 } 74 } 75 } 76 } 77 int ans = Gauss(N, N); 78 if(ans == -1) printf("0 "); 79 else printf("%d ", (1<<ans)); 80 81 } 82 return 0; 83 }