Description
The widget factory produces several different
kinds of widgets. Each widget is carefully built by a skilled widgeteer. The
time required to build a widget depends on its type: the simple widgets need
only 3 days, but the most complex ones may need as many as 9
days.
The factory is currently in a state of complete chaos:
recently, the factory has been bought by a new owner, and the new director has
fired almost everyone. The new staff know almost nothing about building widgets,
and it seems that no one remembers how many days are required to build each
diofferent type of widget. This is very embarrassing when a client orders
widgets and the factory cannot tell the client how many days are needed to
produce the required goods. Fortunately, there are records that say for each
widgeteer the date when he started working at the factory, the date when he was
fired and what types of widgets he built. The problem is that the record does
not say the exact date of starting and leaving the job, only the day of the
week. Nevertheless, even this information might be helpful in certain cases: for
example, if a widgeteer started working on a Tuesday, built a Type 41 widget,
and was fired on a Friday,then we know that it takes 4 days to build a Type 41
widget. Your task is to figure out from these records (if possible) the number
of days that are required to build the different types of widgets.
Input
The input contains several blocks of test cases.
Each case begins with a line containing two integers: the number 1 ≤ n ≤ 300 of
the different types, and the number 1 ≤ m ≤ 300 of the records. This line is
followed by a description of the m records. Each record is described by two
lines. The first line contains the total number 1 ≤ k ≤ 10000 of widgets built
by this widgeteer, followed by the day of week when he/she started working and
the day of the week he/she was fired. The days of the week are given bythe
strings `MON‘, `TUE‘, `WED‘, `THU‘, `FRI‘, `SAT‘ and `SUN‘. The second line
contains k integers separated by spaces. These numbers are between 1 and n , and
they describe the diofferent types of widgets that the widgeteer built. For
example, the following two lines mean that the widgeteer started working on a
Wednesday, built a Type 13 widget, a Type 18 widget, a Type 1 widget, again a
Type 13 widget,and was fired on a Sunday.
4 WED SUN
13 18
1 13
Note that the widgeteers work 7 days a week, and they were
working on every day between their first and last day at the factory (if you
like weekends and holidays, then do not become a widgeteer!).
The
input is terminated by a test case with n = m = 0 .
Output
For each test case, you have to output a single
line containing n integers separated by spaces: the number of days required to
build the different types of widgets. There should be no space before the first
number or after the last number, and there should be exactly one space between
two numbers. If there is more than one possible solution for the problem, then
write `Multiple solutions.‘ (without the quotes). If you are sure that there is
no solution consistent with the input, then write `Inconsistent data.‘(without
the quotes).
题目大意:有n个装饰品,每个装饰品要生产3~9天。给出m种作业,每个作业生产k种装饰品,从星期X生产到星期Y(未必是同一个星期,一天只能生产一个产品),然后给出这k种装饰品分别是什么。问是否能求出n个装饰品分别须要多少天来生产,若有多组解输出Multiple
solutions.,无解输出Inconsistent data.。
思路:可以列出m个方程组成方程组。对于每一个作业,设ki为生产装饰品 i
多少次(用输入数据统计一下就好),xi为生产装饰品 i 需要多少天,那么可以列出方程
k1 * x1 + k2 * x2 + …… + kn * xn = Y - X + 1(mod
7)。
得出方程组后,用高斯消元解,其中需要保证每个系数的范围都在0~6中,除法可以对7求逆元。
消掉下三角之后,若存在k1, k2, …… , kn =
0而右边系数不为0的方程,则无解。
若矩阵的秩rank < n则方程有多组解。
否则算出每一个xi,若xi < 3则 xi += 7
PS:白书训练指南上的模板居然有BUG!
代码(2360MS):

1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #include <cstring>
5 #include <string>
6 #include <map>
7 using namespace std;
8
9 int inv[7];
10
11 struct MOD7 {
12 int val;
13 MOD7() {}
14 MOD7(int val): val((val + 7) % 7) {}
15 MOD7 operator + (const MOD7 &rhs) const {
16 return MOD7(val + rhs.val);
17 }
18 MOD7 operator - (const MOD7 &rhs) const {
19 return MOD7(val - rhs.val);
20 }
21 MOD7 operator * (const MOD7 &rhs) const {
22 return MOD7(val * rhs.val);
23 }
24 MOD7 operator / (const MOD7 &rhs) const {
25 return MOD7(val * inv[rhs.val]);
26 }
27 void operator -= (const MOD7 &rhs) {
28 val = (val - rhs.val + 7) % 7;
29 }
30 bool isZero() {
31 return val == 0;
32 }
33 void inc() {
34 val = (val + 1) % 7;
35 }
36 void print() {
37 if(val < 3) printf("%d", val + 7);
38 else printf("%d", val);
39 }
40 };
41
42 map<string, int> mymap;
43
44 void init() {
45 for(int i = 1; i < 7; ++i) {
46 inv[i] = 1;
47 for(int j = 1; j < 6; ++j) inv[i] = (inv[i] * i) % 7;
48 }
49 mymap["MON"] = 1;
50 mymap["TUE"] = 2;
51 mymap["WED"] = 3;
52 mymap["THU"] = 4;
53 mymap["FRI"] = 5;
54 mymap["SAT"] = 6;
55 mymap["SUN"] = 0;
56 }
57
58 const int MAXN = 310;
59
60 MOD7 mat[MAXN][MAXN];
61 int n, m;
62
63 int guess_eliminatioin() {
64 int rank = 0;
65 for(int i = 0, t = 0; i < m && t < n; ++i, ++t) {
66 int r = i;
67 for(int j = i + 1; j < m; ++j)
68 if(mat[r][t].val < mat[j][t].val) r = j;
69 if(mat[r][t].isZero()) { --i; continue;}
70 else ++rank;
71 if(r != i) for(int j = 0; j <= n; ++j) swap(mat[i][j], mat[r][j]);
72 for(int j = n; j >= t; --j)
73 for(int k = i + 1; k < m; ++k) mat[k][j] -= mat[i][j] * mat[k][t] / mat[i][t];
74 }
75 for(int i = rank; i < m; ++i)
76 if(!mat[i][n].isZero()) return -1;
77 if(rank < n) return 0;
78 for(int i = n - 1; i >= 0; --i) {
79 for(int j = i + 1; j < n; ++j)
80 mat[i][n] -= mat[j][n] * mat[i][j];
81 mat[i][n] = mat[i][n] / mat[i][i];
82 }
83 return 1;
84 }
85
86 int main() {
87 init();
88 while(scanf("%d%d", &n, &m) != EOF) {
89 if(n == 0 && m == 0) break;
90 memset(mat, 0, sizeof(mat));
91 int t, p;
92 string s1, s2;
93 for(int i = 0; i < m; ++i) {
94 cin>>t>>s1>>s2;
95 while(t--) {
96 scanf("%d", &p);
97 mat[i][p - 1].inc();
98 }
99 mat[i][n] = MOD7(mymap[s2] - mymap[s1] + 8);
100 }
101 int result = guess_eliminatioin();
102 if(result == -1) puts("Inconsistent data.");
103 else if(result == 0) puts("Multiple solutions.");
104 else {
105 for(int i = 0; i < n - 1; ++i) {
106 mat[i][n].print();
107 putchar(‘ ‘);
108 }
109 mat[n - 1][n].print();
110 puts("");
111 }
112 }
113 }
View Code
POJ 2947 Widget Factory(高斯消元),布布扣,bubuko.com
POJ 2947 Widget Factory(高斯消元)
原文:http://www.cnblogs.com/oyking/p/3614942.html