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

来源:互联网 发布:数据线材厂家 编辑:程序博客网 时间:2024/05/27 21:12

链接:poj 2947

题意:生产一些零件,已知零件种数,记录条数

记录只记录了某次生产从周几开始,周几结束,以及生产了哪些产品。

每件商品生产所需天数为3-9天。

求每样产品需要多少天才能完成。

若无解输出Inconsistent data.

有无穷解输出Multiple solutions.

有唯一解,输出其解

分析:根据题目所给信息,可以列出同余方程组,再根据高斯消元求解,

但还得判断是无解,无穷解,还是唯一解

1.系数矩阵的秩若与增广矩阵的秩不相等,则无解,否则有解

2.若有解,若增广矩阵的秩小于未知数的个数,则有无穷解

3.若有解,增广矩阵的秩等于未知数的个数,则有唯一解

有唯一解时,需要用扩展欧几里得解模线性方程

注:求矩阵的秩,先将矩阵化为阶梯型,有多少个非0行或者非0列,

矩阵的秩就为多少.矩阵的行秩等于矩阵的列秩


#include<stdio.h>#include<string.h>#include<algorithm>#define MOD 7using namespace std;int m,n,matrix[310][310],ans[310];int get_id(char s[]){    char week[8][5]={"","MON","TUE","WED","THU","FRI","SAT","SUN"};    int i;    for(i=1;i<=7;i++)        if(strcmp(s,week[i])==0)            break;    return i;}int ex_gcd(int a,int b,int &x,int &y){    int t,d;    if(b==0){        x=1;        y=0;        return a;    }    d=ex_gcd(b,a%b,x,y);    t=x;    x=y;    y=t-a/b*y;    return d;}int Lcm(int a,int b){    int x,y;    return a*b/ex_gcd(a,b,x,y);}int guass(){    int i,j,row,col;    for(row=0,col=0;row<n&&col<m;row++,col++){        for(i=row;i<n;i++)            if(matrix[i][col])                break;        if(i==n){          //col列全为0            row--;            continue;        }        if(i!=row)            for(j=0;j<=m;j++)                swap(matrix[row][j],matrix[i][j]);   //交换两行        for(i=row+1;i<n;i++){                      if(matrix[i][col]){                int lcm=Lcm(matrix[row][col],matrix[i][col]);                int t1=lcm/matrix[i][col],t2=lcm/matrix[row][col];                for(j=col;j<=m;j++)                    matrix[i][j]=((matrix[i][j]*t1-matrix[row][j]*t2)%MOD+MOD)%MOD;            }        }    }    for(i=row;i<n;i++)             if(matrix[i][m])          //无解            return -1;    if(row<m)                    //有无穷解        return 0;    memset(ans,0,sizeof(ans));  //唯一解求解过程如下    for(i=n-1;i>=0;i--){                int temp=0;        for(j=i+1;j<m;j++)            temp=(temp+matrix[i][j]*ans[j]%MOD)%MOD;        int b=((matrix[i][m]-temp)%MOD+MOD)%MOD;        int x,y;        int d=ex_gcd(matrix[i][i],MOD,x,y);  //解模线性方程        x=x*(b/d)%MOD;        x=(x%(MOD/d)+(MOD/d))%(MOD/d);        ans[i]=x;        if(ans[i]<3)            ans[i]+=7;    }    return 1;}int main(){    int num,i,j,type;    char start[5],end[5];    while(scanf("%d%d",&m,&n)!=EOF){        if(m==0&&n==0)            break;        memset(matrix,0,sizeof(matrix));        for(i=0;i<n;i++){            scanf("%d%s%s",&num,start,end);            matrix[i][m]=((get_id(end)-get_id(start)+1)%MOD+MOD)%MOD; //求生产时间对7取余            for(j=1;j<=num;j++){                scanf("%d",&type);                matrix[i][type-1]=(matrix[i][type-1]+1)%MOD;   //记录矩阵的值            }        }        int flag=guass();   //高斯消元        if(flag==-1)            printf("Inconsistent data.\n");        else if(flag==0)            printf("Multiple solutions.\n");        else{            for(i=0;i<m-1;i++)                printf("%d ",ans[i]);            printf("%d\n",ans[m-1]);        }    }    return 0;}


1 0