首页 > 代码库 > poj 2947 Widget Factory (高斯消元,解模线性方程)
poj 2947 Widget Factory (高斯消元,解模线性方程)
链接:poj 2947
题意:生产一些零件,已知零件种数,记录条数
记录只记录了某次生产从周几开始,周几结束,以及生产了哪些产品。
每件商品生产所需天数为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; }
poj 2947 Widget Factory (高斯消元,解模线性方程)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。