题意:生产一些零件,已知零件种数,记录条数
记录只记录了某次生产从周几开始,周几结束,以及生产了哪些产品。
每件商品生产所需天数为3-9天。
求每样产品需要多少天才能完成。
若无解输出Inconsistent data.
有无穷解输出Multiple solutions.
有唯一解,输出其解
分析:根据题目所给信息,可以列出同余方程组,再根据高斯消元求解,
但还得判断是无解,无穷解,还是唯一解
1.系数矩阵的秩若与增广矩阵的秩不相等,则无解,否则有解
2.若有解,若增广矩阵的秩小于未知数的个数,则有无穷解
3.若有解,增广矩阵的秩等于未知数的个数,则有唯一解
有唯一解时,需要用扩展欧几里得解模线性方程
注:求矩阵的秩,先将矩阵化为阶梯型,有多少个非0行或者非0列,
矩阵的秩就为多少.矩阵的行秩等于矩阵的列秩
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MOD 7
using 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;
}