您的位置:首页 > 其它

zoj 3155 Street Lamp 高斯消元 异或方程组 求方案数

2016-04-15 21:33 411 查看
题目链接:http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3155

题意:给出一张图有灯泡的连接关系和初始灯泡状态,相邻的灯泡如果相连则可以相互影响,求使所有灯泡最后都关闭的不同操作的情况数。

和poj1222差不多,不过这题求的是方案数。

#include <bits/stdc++.h>
using namespace std;
#define maxn 12
int a[maxn*maxn][maxn*maxn];
char mp[maxn*2][maxn*2];
int n, m;
int Gauss(int n, int m)
{
int r, c;
for(r = 0, c = 0; r < n && c < m; r++, c++)
{
int max_r = r;
for(int i = r+1; i < n; i++)
{
if(fabs(a[i][c]) > fabs(a[max_r][c])) max_r = i;
}
if(a[max_r][c] == 0){r--; continue;}
if(max_r != r)
{
for(int i = r; i < m+1; i++) swap(a[r][i], a[max_r][i]);
}

for(int i = r+1; i < n; i++)
{
if(a[i][c] == 0) continue;
for(int j = r; j < m+1; j++)
{
a[i][j] ^= a[r][j];
}
}
}

for(int i = r; i < n; i++)
{
if(a[i][c]) return -1;
}
if(r < m) return m-r;
else return 0;
}
int main()
{
//freopen("in.txt", "r", stdin);
while(~scanf("%d%d", &n, &m))
{
getchar();
for(int i = 0; i < 2*n-1; i++)
{
string s;
getline(cin, s);
for(int j = 0; j < 2*m-1; j++) mp[i][j] = s[j];
}
memset(a, 0, sizeof(a));
int N = n*m;
for(int i = 0; i < N; i++) a[i][i] = 1;

for(int i = 0; i < 2*n-1; i++)
{
for(int j = 0; j < 2*m-1; j++)
{
if(i%2)
{
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;
}
else
{
if(j%2)
{
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;
}
else
{
if(mp[i][j] == 'o') a[(i/2)*m+j/2]
= 1;
}
}
}
}
int ans = Gauss(N, N);
if(ans == -1) printf("0\n");
else printf("%d\n", (1<<ans));

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: