题解
题解
设制作第
i
i
i 类装置需要的时间为
x
i
x_i
xi,对于每条记录,统计在工人工作时间内各类装置制作的数量
a
i
a_i
ai,设开始、结束的星期数之差为
b
i
b_i
bi,由于不知道工人开始、结束工作相隔多少周,于是得到一个模数为
7
7
7 的线性同余方程
∑
i
=
0
n
−
1
a
i
x
i
=
b
i
m
o
d
7
\sum\limits_{i=0}^{n-1}a_ix_i=b_i\mod 7
i=0∑n−1aixi=bimod7 共
m
m
m 条记录,故得到一个方程数为
m
m
m,未知数个数为
n
n
n 的线性同余方程组。已知
x
i
∈
[
3
,
9
]
x_i\in [3,9]
xi∈[3,9] 正好与模
7
7
7 的余数一一对应,高斯消元求解线性同余方程组,若方程无非零主元的行出现非零的
b
i
b_i
bi,方程无解;若有解,增广矩阵秩小于
n
n
n,则方程有多组解;其余情况有唯一解,求
x
i
x_i
xi 的系数的逆元,最终可得到
x
i
x_i
xi。
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
typedef vector<int> vec;
typedef vector<vec> mat;
const int mod = 7;
int N, M;
map<string, int> mp;
int qpow(int x, int n)
{
int res = 1;
while (n)
{
if (n & 1)
res = res * x % mod;
x = x * x % mod, n >>= 1;
}
return res;
}
void gauss_jordan(const mat &A, const vec &b)
{
int m = A.size(), n = A[0].size();
mat B(m, vec(n + 1));
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
B[i][j] = A[i][j];
for (int i = 0; i < m; ++i)
B[i][n] = b[i];
int p = 0;
for (int i = 0; i < n; ++i)
{
if (p >= m)
break;
int tmp = p;
for (int j = p + 1; j < m; ++j)
if (B[j][i] > B[tmp][i])
tmp = j;
swap(B[p], B[tmp]);
if (B[p][i] == 0)
continue;
for (int j = 0; j < m; ++j)
{
int y = B[j][i];
if (j != p)
{
for (int k = 0; k <= n; ++k)
B[j][k] = ((B[j][k] * B[p][i] - y * B[p][k]) % mod + mod) % mod;
}
}
++p;
}
for (int i = p; i < m; ++i)
if (B[i][n])
{
puts("Inconsistent data.");
return;
}
if (p < n)
{
puts("Multiple solutions.");
return;
}
for (int i = 0; i < n; ++i)
{
int v = qpow(B[i][i], mod - 2), d = B[i][n] * v % mod;
printf("%d%c", d >= 3 ? d : d + 7, i + 1 == n ? '\n' : ' ');
}
}
int main()
{
mp["MON"] = 1, mp["TUE"] = 2, mp["WED"] = 3, mp["THU"] = 4, mp["FRI"] = 5, mp["SAT"] = 6, mp["SUN"] = 7;
while (~scanf("%d%d", &N, &M) && (N | M))
{
mat A(M, vec(N, 0));
vec b(M, 0);
for (int i = 0; i < M; ++i)
{
int k, t;
char s1[5], s2[5];
scanf("%d %s %s", &k, s1, s2);
b[i] = (mp[s2] - mp[s1] + 1 + mod) % mod;
for (int j = 0; j < k; ++j)
{
scanf("%d", &t);
A[i][t - 1]++;
}
for (int j = 0; j < N; ++j)
A[i][j] %= mod;
}
gauss_jordan(A, b);
}
return 0;
}