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

来源:互联网 发布:诺基亚windows手机 编辑:程序博客网 时间:2024/05/16 03:39

有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_pairtypedef 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;}


0 0