您的位置:首页 > 其它

POJ-1830 开关问题(高斯消元)

2015-08-10 16:27 417 查看
代码的大部分都是和poj1222一样的,求出自由变元个数就好了。

1222题解:http://blog.csdn.net/moringrain/article/details/47397787

这道题需要学习的地方是如何处理初始状态和目标状态。

初始状态-->目标状态 等同于 全0状态-->初始状态 xor 目标状态

另外给系数赋值的时候注意行列的顺序,一开始搞错了调了半天(样例很弱,一开始错了也能过)

总之,这类题在给系数赋值的时候一定要多过脑子。

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAXN = 50; //未知数数目
int equ, var;        //equ个方程,var个变元
int a[MAXN][MAXN];   //行数为equ,0~var列为系数,var列为得数
int x[MAXN];         //解集
int free_num;        //自由变元数量
int free_x[MAXN];    //自由变元,多解枚举时会用到

/*******************************************************
*               mod2高斯消元过程
*       返回-1无解,0惟一解,>0自由变元数目
*******************************************************/
int Gauss()
{
	int maxr, col, i, j, k;
	free_num = 0;
	for (k = 0, col = 0; k<equ && col<var; k++, col++)
	{
		maxr = k;
		for (i = k + 1; i<equ; i++)
		{
			if (abs(a[i][col])>abs(a[maxr][col]))
				maxr = i;
		}
		if (a[maxr][col] == 0)
		{
			k--;
			free_x[free_num++] = col;	              //出现一个自由变元
			continue;
		}
		if (maxr != k)
		{
			for (j = col; j<var + 1; j++)
				swap(a[k][j], a[maxr][j]);
		}
		for (i = k + 1; i<equ; i++)
		{
			if (a[i][col] != 0)
			{
				for (j = col; j<var + 1; j++)
					a[i][j] ^= a[k][j];
			}
		}
	}
	for (i = k; i<equ; i++)
		if (a[i][col] != 0)
			return -1;              //无解情况
	if (k<var)
		return var - k;             //多个自由变元

	for (i = var - 1; i >= 0; i--)  //惟一解,进行回代
	{
		x[i] = a[i][var];
		for (j = i + 1; j<var; j++)
			x[i] ^= (a[i][j] && x[j]);
	}
	return 0;
}

void work()
{
	int i, j, n, k, t, ans;
	int inital_sate[MAXN], target_state[MAXN];

	memset(a, 0, sizeof(a));
	memset(x, 0, sizeof(x));

	scanf("%d",&n);
	equ = var = n;
	for (i = 0; i < n; i++)
		scanf("%d", &inital_sate[i]);
	for (i = 0; i < n; i++)
		scanf("%d", &target_state[i]);
	for (i = 0; i < n; i++)
	{
		a[i][i] = 1;
		a[i]
 = inital_sate[i] ^ target_state[i];
	}

	while (scanf("%d%d", &k, &t) == 2)
	{
		if (k == 0 && t == 0) break;
		a[t - 1][k - 1] = 1;    //注意kt别写反了
	}

	ans = Gauss();
	if (ans == -1)
		printf("Oh,it's impossible~!!\n");
	else
		printf("%d\n",(1<<ans));
}

int main()
{
	int T;
	scanf("%d", &T);
	while (T--)
		work();
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: