您的位置:首页 > 其它

poj -- 2947 Widget Factory(高斯消元)

2014-05-08 16:26 381 查看
有n种产品,m个员工,每个员工在给定的两个日期(可能持续几周)中间做了ki件产品,并给出了这ki见产品的类型。求每件产品需要多少天生产(3~9天)。

http://poj.org/problem?id=2947

高斯消元法解模线性方程组。

n种产品对应n个变量,m个员工对应m个方程,方程的解为(start - end + 1 +7 )% 7.

然后运用高斯消元求解。

若无解输出Inconsistent data.

若有自由变元存在(即有多个解)输出Multiple solutions。

有唯一解就输出解。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define pb push_back
#define MP make_pair

typedef long long ll;
typedef pair<int, int> PII;

const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int maxn = 400 + 10;

int dxy[4][2] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };
int n, m;
char str[20];
int equ, var, a[maxn][maxn], x[maxn], free_num;
bool free_x[maxn];
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
int lcm(int a, int b){
return a / gcd(a, b) * b;
}
void init(){
memset(a, 0, sizeof(a));
memset(x, 0, sizeof(x));
memset(free_x, true, sizeof(free_x));
equ = m;
var = n;
}
void Debug(){
puts("debug");
for(int i=0; i<equ; i++)
for(int j=0; j<=var; j++)
printf("%d%c", a[i][j], j == var ? '\n' : ' ');
puts("end");
}
void Guass(){
int col, row, mx;
//    Debug();
for(col=0,  row=0; col<var&&row<equ; col++, row++){
mx = row;
for(int i=row+1; i<equ; i++)
if(abs(a[i][col]) > abs(a[mx][col])) mx = i;
if(a[mx][col] == 0){
row--;
continue;
}
if(mx != row)
for(int i=col; i<=var; i++)
swap(a[mx][i], a[row][i]);
for(int i=row+1; i<equ; i++){
if(a[i][col] == 0) continue;
int LCM = lcm(abs(a[i][col]), abs(a[row][col]));
int ta = LCM / abs(a[i][col]);
int tb = LCM / abs(a[row][col]);
if(a[i][col] * a[row][col] < 0) tb = -tb;
for(int j=col; j<=var; j++){
a[i][j] = ((a[i][j] * ta - a[row][j] * tb) % 7 + 7) % 7 ;
}
}
}
//    Debug();
for(int i=row; i<equ; i++)
if(a[i][var] != 0){
puts("Inconsistent data.");
return;
}
if(row == var){
for(int i=var-1; i>=0; i--){
int tmp = a[i][var];
for(int j=i+1; j<var; j++)
if(a[i][j]){
tmp -= a[i][j] * x[j];
while(tmp <  0) tmp += 7;
tmp %= 7;
}
while(tmp % a[i][i] != 0) tmp += 7;//保证相除之后是整数
x[i] = (tmp / a[i][i]) % 7;
}
for(int i=0; i<var; i++){
if(x[i] <= 2) x[i] += 7;//根据题意每个解都要大于2
printf("%d%c", x[i], i == var-1 ? '\n' : ' ');
}
return;
}
puts("Multiple solutions.");
}
int main(){
map<string, int> week;
week.clear();
week["MON"] = 1; week["TUE"] = 2; week["WED"] = 3; week["THU"] = 4; week["FRI"] = 5; week["SAT"] = 6; week["SUN"] = 7;
while(scanf("%d%d", &n, &m) == 2){
if(!n && !m) break;
init();
int k, l, r, tmp;
string s1, s2;
for(int i=0; i<m; i++){
cin >> k >> s1 >> s2;
l = week[s1]; r = week[s2];
a[i][var] = (r - l + 1 + 7) % 7;
while(k--){
scanf("%d", &tmp);
tmp--;//编号为0~n-1
a[i][tmp]++;
a[i][tmp] %= 7;
}
}
Guass();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  高斯消元