POJ 1830 开关问题 高斯消元

题目大意:给出灯的一些关系,求有多少种方法从始状态到终状态。


思路:其实根据灯的这些关系就可以列出一系列方程,然后用高斯消元就可以求出自由元的数量,答案就是2^自由元的数量。


CODE:


#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 50
using namespace std;

int cnt;
int a[MAX][MAX];

inline int Gauss()
{
	int re = 0,now = 1;
	for(int j,i = 1; i <= cnt; ++i) {
		for(j = now; j <= cnt && !a[j][i]; ++j);
		if(j > cnt) {
			++re;
			continue;
		}
		for(int k = 1; k <= cnt + 1; ++k)
			swap(a[now][k],a[j][k]);
		for(j = now + 1; j <= cnt; ++j)
			if(a[j][i])
				for(int k = i; k <= cnt + 1; ++k)
					a[j][k] ^= a[now][k];
		++now;
	}
	for(int i = now; i <= cnt; ++i)
		if(a[i][cnt + 1])
			return -1;
	return 1 << re;
}

int main()
{
	int T;
	for(cin >> T; T--;) {
		memset(a,0,sizeof(a));
		scanf("%d",&cnt);
		for(int i = 1; i <= cnt; ++i)
			scanf("%d",&a[i][cnt + 1]);
		for(int x,i = 1; i <= cnt; ++i) {
			scanf("%d",&x);
			a[i][cnt + 1] ^= x;
		}
		int x,y;
		while(scanf("%d%d",&x,&y),x + y)
			a[y][x] = 1;
		for(int i = 1; i <= cnt; ++i)
			a[i][i] = 1;
		int ans = Gauss();
		if(ans == -1)	puts("Oh,it's impossible~!!");
		else	printf("%d\n",ans);
	}
	return 0;
}

你可能感兴趣的:(poj,高斯消元)