poj 2947 Widget Factory(模7环上的高斯消元)

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

大致题意:

有n种装饰物,m个已知条件,每个已知条件的描述如下:

p start end

a1,a2......ap (1<=ai<=n)

第一行表示从星期start到星期end一共生产了p件装饰物(工作的天数为end-start+1+7*x,加7*x是因为它可能生产很多周),第二行表示这p件装饰物的种类(可能出现相同的种类,即ai=aj)。规定每件装饰物至少生产3天,最多生产9天。问每种装饰物需要生产的天数。如果没有解,则输出“Inconsistent
data.”,如果有多解,则输出“Multiple solutions.”,如果只有唯一解,则输出每种装饰物需要生产的天数。

思路:依旧是高斯消元。这里的m个已知条件就是m个方程组,n为n个未知数。设生产第i个装饰物需要的天数为x(i),生产第i个装饰物的件数是A(i)件,那么对于每一个方程有x(1)*A(1) +

x(2)*A(2)  + ...
x(n)*A(n)= end-start+1+7*x。

注意:

因为是模线性方程,形成增广阵时要不断的模7.

注意模7环上的求解方法.

当有唯一解时要求每件装饰物的生产天数为[3,9]。所以要判断是否满足条件,否则加7.

#include <stdio.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#define LL long long
#define _LL __int64
using namespace std;

int equ,var;
int a[310][310];
int x[310];

int trans(char s[])
{
    if(strcmp(s,"MON") == 0)
        return 1;
    if(strcmp(s,"TUE") == 0)
        return 2;
    if(strcmp(s,"WED") == 0)
        return 3;
    if(strcmp(s,"THU") == 0)
        return 4;
    if(strcmp(s,"FRI") == 0)
        return 5;
    if(strcmp(s,"SAT") == 0)
        return 6;
    if(strcmp(s,"SUN") == 0)
        return 7;
}

void init()
{
    memset(a,0,sizeof(a));
    memset(x,0,sizeof(x));
}

int inline gcd(int a, int b)
{
    if(b == 0)
        return a;
    return gcd(b,a%b);
}

int inline lcm(int a, int b)
{
    return a/gcd(a,b)*b;
}

int Gauss()
{
    int row,col,i,j,max_r;

    row = col = 0;

    while(row < equ && col < var)
    {
        max_r = row;
        for(i = row+1; i < equ; i++)
            if( abs(a[i][col]) > abs(a[max_r][col]) )
                max_r = i;

        if(max_r != row)
        {
            for(j = col; j < var+1; j++)
                swap(a[row][j],a[max_r][j]);
        }

        if(a[row][col] == 0)
        {
            col++;
            continue;
        }

        for(i = row+1; i < equ; i++)
        {
            if(a[i][col] == 0) continue;

            int l = lcm( abs(a[row][col]), abs(a[i][col]) );
            int ta = l/a[i][col],tb = l/a[row][col];
            if(a[i][col] * a[row][col] < 0) tb = -tb;

            for(j = col; j < var+1; j++)
                a[i][j] = ( (a[i][j]*ta - a[row][j]*tb) % 7 + 7 ) % 7; //mod 7
        }
        row++;
        col++;
    }

    for(i = row; i < equ; i++)
        if(a[i][col] != 0)
            return -1;

    if(row < var)
        return var-row;

    for(i = var-1; i >= 0; i--)
    {
        //求唯一解
        int tmp = a[i][var];
        for(j = i+1; j < var; j++)
        {
            if(a[i][j] != 0)
                tmp = ( (tmp-a[i][j]*x[j])%7 + 7 )%7;
        }

        while(tmp%a[i][i] != 0)
            tmp += 7;
        x[i] = tmp/a[i][i]%7;
    }
    return 0;
}

int main()
{
    int n,m,t;
    char s1[10],s2[10];

    while(~scanf("%d %d",&n,&m))
    {
        if(n == 0 && m == 0) break;
        init();
        for(int i = 0; i < m; i++)
        {
            scanf("%d %s %s",&t,s1,s2);
            a[i][n] = ( (trans(s2)-trans(s1) + 1) % 7 + 7 )%7;
            while(t--)
            {
                int tmp;
                scanf("%d",&tmp);
                tmp--;
                a[i][tmp]++;
                a[i][tmp] %= 7;
            }
        }
        equ = m;
        var = n;
        int res = Gauss();
        if(res == -1)
            printf("Inconsistent data.\n");
        else if(res > 0)
            printf("Multiple solutions.\n");
        else
        {
            for(int i = 0; i < var; i++)
                if(x[i] <= 2)
                    x[i] += 7;
            for(int i = 0; i < var-1; i++)
                printf("%d ",x[i]);
            printf("%d\n",x[var-1]);
        }
    }
    return 0;
}
时间: 2024-11-10 17:37:26

poj 2947 Widget Factory(模7环上的高斯消元)的相关文章

POJ 2947 Widget Factory (高斯消元 判多解 无解 和解集 模7情况)

题目链接 题意: 公司被吞并,老员工几乎全部被炒鱿鱼.一共有n种不同的工具,编号1-N(代码中是0—N-1), 每种工具的加工时间为3—9天 ,但是现在老员工不在我们不知道每种工具的加工时间,庆幸的是还保留着一些对工人制造工具的记录,对于每个老员工,他的记录包括,他开始工作的时间(在某个星期的星期几),被炒鱿鱼的时间(某个星期的星期几),在第几个星期不知道.....在这段时间里,他正好加工了k件物品,给出了这k件物品的编号.我们要做的就是通过这些记录,来确定每种工具的加工时间是多少. 分析: 对

[ACM] POJ 2947 Widget Factory (高斯消元)

Widget Factory Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 4436   Accepted: 1502 Description The widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to

POJ - 1222: EXTENDED LIGHTS OUT (开关问题-高斯消元)

pro:给定5*6的灯的状态,如果我们按下一个灯的开关,它和周围4个都会改变状态.求一种合法状态,使得终状态全为关闭: sol:模2意义下的高斯消元. 终于自己手打了一个初级板子. #include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; int a[40][40],ans[40]; int x[5]={0,0,0,1,-1}; int y[5]={0,1,-1,0,0};

poj 2947 Widget Factory (高斯消元,解模线性方程)

链接:poj 2947 题意:生产一些零件,已知零件种数,记录条数 记录只记录了某次生产从周几开始,周几结束,以及生产了哪些产品. 每件商品生产所需天数为3-9天. 求每样产品需要多少天才能完成. 若无解输出Inconsistent data. 有无穷解输出Multiple solutions. 有唯一解,输出其解 分析:根据题目所给信息,可以列出同余方程组,再根据高斯消元求解, 但还得判断是无解,无穷解,还是唯一解 1.系数矩阵的秩若与增广矩阵的秩不相等,则无解,否则有解 2.若有解,若增广矩

poj 2947 Widget Factory

Widget Factory 题意:有n件装饰品,有m组信息.(1 <= n ,m<= 300)每组信息有开始的星期和结束的星期(是在mod 7范围内的)并且还包括num种装饰品的种类(1~n),其中每种装饰品所用的时间3 <= x[i] <= 9;种类的输入可以重复: 思路: 1.根据输入建立增广矩阵a[][],但是在建立和求解的过程中由于是mod意义下的,所以输入的个数和最终所用的时间都要mod 7;(分析可知当个数是7的同余类时,开始星期相同则结束星期也相同) 2.前面几个高

poj 2947 Widget Factory(高斯消元)

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

Poj 2947 widget factory (高斯消元解同模方程)

题目连接: http://poj.org/problem?id=2947 题目大意: 有n种类型的零件,m个工人,每个零件的加工时间是[3,9],每个工人在一个特定的时间段内可以生产k个零件(可以相同种类,也可以不同种类),问每种零件生产一个出来需要的时间? 解题思路: 给出的时间段是从周几到周几,并没有给出具体的时间段,因此在计算过程中要进行取模,还有就是对每个零件要在题目要求的范围内进行枚举. ps:如果求出来的增广矩阵是n*n的,但是某个零件在[3,9]之间没有合理的解,也是无解的. 1

poj 2947 Widget Factory (高斯消元解同余方程组+判断无解、多解)

http://poj.org/problem?id=2947 血泪史: CE:poj的string类型要加string库,swap不能直接交换数组 WA: x[m-1]也有可能<3啊O(≧口≦)O #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int mod=7; int n,m; char ch[

【POJ】2947 Widget Factory(高斯消元)

http://poj.org/problem?id=2947 各种逗啊..还好1a了.. 题意我就不说了,百度一大把. 转换为mod的方程组,即 (x[1,1]*a[1])+(x[1,2]*a[2])+...+(x[1,n]*a[n])=x[1, n+1] (mod m) (x[2,1]*a[1])+(x[2,2]*a[2])+...+(x[2,n]*a[n])=x[2, n+1] (mod m) ... (x[n,1]*a[1])+(x[n,2]*a[2])+...+(x[n,n]*a[n])