POJ 2947 高斯消元法解同余方程组

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 1E3 + 10;
const int MOD = 7;
char s1[5], s2[5];
int n, m, k, tmp, inp[maxn][maxn], x[maxn];
int gcd(int a, int b)
{
	if (b > a) swap(a, b);
	return b == 0 ? a : gcd(b, a % b);
}
int lcm(int a, int b)
{
	return a / gcd(a, b) * b;
}
long long inv(long long a, long long m)
{
	if (a == 1) return 1;
	return inv(m % a, m) * (m - m / a) % m;
}
int Gauss(int equ, int var)
{
	int max_r, col, k;
	for (k = 0, col = 0; k < equ && col < var; k++, col++)
	{
		max_r = k;
		for (int i = k + 1; i < equ; i++)
			if (abs(inp[i][col]) > abs(inp[max_r][col]))
				max_r = i;
		if (inp[max_r][col] == 0) {k--; continue;}
		if (max_r != k) for (int j = col; j < var + 1; j++) swap(inp[k][j], inp[max_r][j]);
		for (int i = k + 1; i < equ; i++)
			if (inp[i][col] != 0)
			{
				int LCM = lcm(abs(inp[i][col]), abs(inp[k][col]));
				int ta = LCM / abs(inp[i][col]);
				int tb = LCM / abs(inp[k][col]);
				if (inp[i][col]*inp[k][col] < 0) tb = -tb;
				for (int j = col; j < var + 1; j++)
					inp[i][j] = ((inp[i][j] * ta - inp[k][j] * tb) % MOD + MOD) % MOD;
			}
	}
	for (int i = k; i < equ; i++) if (inp[i][col] != 0) return -1;
	if (k < var) return var - k;
	for (int i = var - 1; i >= 0; i--)
	{
		int temp = inp[i][var];
		for (int j = i + 1; j < var; j++)
		{
			if (inp[i][j] != 0)
			{
				temp -= inp[i][j] * x[j];
				temp = (temp % MOD + MOD) % MOD;
			}
		}
		x[i] = (temp * inv(inp[i][i], MOD)) % MOD;
	}
	return 0;
}
int week(char *s)
{
	if (!strcmp(s, "MON"))return 1;
	if (!strcmp(s, "TUE"))return 2;
	if (!strcmp(s, "WED"))return 3;
	if (!strcmp(s, "THU"))return 4;
	if (!strcmp(s, "FRI"))return 5;
	if (!strcmp(s, "SAT"))return 6;
	if (!strcmp(s, "SUN"))return 7;
}
int main(int argc, char const *argv[])
{
	while (~scanf("%d%d", &n, &m) && n + m)
	{
		memset(inp, 0, sizeof(inp));
		memset(x, 0, sizeof(x));
		for (int i = 0; i < m; i++)
		{
			scanf("%d%s%s", &k, s1, s2);
			inp[i][n] = ((week(s2) - week(s1) + 1) % 7 + 7) % 7;
			while (k--)
			{
				scanf("%d", &tmp);
				inp[i][--tmp]++, inp[i][tmp] %= 7;
			}
		}
		int ans = Gauss(m, n);
		if (ans == 0)
		{
			for (int i = 0; i < n; i++)
				if (x[i] <= 2) x[i] += 7;
			for (int i = 0; i < n; ++i) printf("%d%c", x[i], i == n - 1 ? '\n' : ' ');
		}
		else if (ans == -1) printf("Inconsistent data.\n");
		else printf("Multiple solutions.\n");
	}
	return 0;
}


n 件物品,m 个条件,p s e a1 a2 .....ap  P件物品从s生产到e,ax表示物品的种类,问每种装饰物需要生产的天数。

高斯消元。设每种装饰物需要生产的天数为xi(1<=i<=n)。每一个条件就相当于

给定了一个方程式,假设生产1 类装饰物a1 件、2 类装饰物a2 件、i 类装饰物ai 件所花费

的天数为b,则可以列出下列方程:a1*x1+a2*x2+...an*xn = b (mod 7)

这样一共可以列出m 个方程式,然后使用高斯消元来解此方程组即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值