您的位置:首页 > 其它

poj 1830 开关问题 高斯消元

2013-06-04 23:41 411 查看
题意:给你n个开关,给定开关的初状态和要达到的末状态,并给出i j 代表操作i也会影响j。

如果有可行方法,输出方法总数。否则输出“Oh,it's impossible~!!”。

这样我们就可以很快根据给定的数据建立一个方程组高斯消元求解。

我们求得的自由变元个数为k,可行方法自然就是(1<<k)。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int a[33][33],st[33],to[33];
int n;
void debug()
{
int i,j;
puts("debug");
for(i = 0;i < n; i++)
{
for(j = 0;j < n+1;j ++)
printf("%d ", a[i][j]);
puts("");
}
puts("end");
}
void gauss()
{
int i,j;
int row = 0, col = 0;
//	debug();
for( ; row < n && col < n ; row++, col++)
{
int maxr = row;
for(i = row+1;i < n; i++)
if(a[i][col])
maxr = i;
if(!a[maxr][col])
{
row--;
continue;
}
if(row != maxr)
for(i = col;i < n+1;i ++)
swap(a[maxr][i] , a[row][i]);
for(i = row+1;i < n; i++)
if(a[i][col])
for(j = col;j < n+1; j++)
a[i][j] ^= a[row][j];
}
//	debug();
for(i = row;i < n; i++)
if(a[i]
)
{
puts("Oh,it's impossible~!!");
return ;
}
printf("%d\n", 1<<(n-row));
}
int main()
{
int i,j,t;
scanf("%d", &t);
while(t--)
{
memset(a,0,sizeof(a));
scanf("%d", &n);
for(i = 0;i < n; i++)
scanf("%d", &st[i]);
for(i = 0;i < n; i++)
scanf("%d", &to[i]);
while(scanf("%d%d", &i, &j) && i)
a[j-1][i-1] = 1;
for(i = 0;i < n ;i++)
a[i][i] = 1;
for(i = 0;i < n; i++)
if(st[i] != to[i])
a[i]
= 1;
gauss();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  POJ 高斯消元