POJ2947-Widget Factory
Posted -chamgin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2947-Widget Factory相关的知识,希望对你有一定的参考价值。
工厂里每件期间的生产时间为3-9天,告诉你有N个器件和M个计划,每个计划都是说明生产1~N号器件的时间,最后问你每件器件的生产时间。或者多解或没有解。
例如样例
2 3 2 MON THU 1 2 3 MON FRI 1 1 2 3 MON SUN 1 2 2
其中 2 MON THU 说明下面有两个器件是星期一到星期四生产的,所以有如下方程:(假设i号器件生产时间为xi)
x1+x2=4
x1+x1+x2=5
x1+x2+x2=7
很明显求方程解可以用高斯消元法,算做一道高斯消元的练习题吧。
高斯消元就是通过初等行变化把矩阵化成阶梯型矩阵,然后从低到顶求解每个变量的值。
注意如果某列对应的都是0,那么求解下一列。
多解的情况就是矩阵的秩小于未知量的个数,因为那些未知量可以取任意的值。
没有解就是得出秩行下面如果某个最后的常数不是0,那么就是无解,因为没有0=m这样的解。
代码如下:
#include <iostream> #include <string.h> #include <string> #include <map> using namespace std; int ma[333][333],n,m; int arr[233],ans; map<string,int> mp; int solve() { int i,j,k=1,l,tmp,num=0,sum; for(i=1;i<=m&&k<=n;++i){ //这里i是当前第i行,k是当前第k列 for(j=i;j<=m;++j) //找一个k列不是0的行 if(ma[j][k]) break; if(j>m){ //找不到那么就处理下一个未知量 --i; ++k; continue; } if(j!=i){ swap(ma[i],ma[j]); } for(j=i+1;j<=m;++j){ if(!ma[j][k]) continue; tmp=ma[j][k];//!!!这里WA了,因为一开始没有保存ma[j][k]的值,如果你不保存那么ma[j][k]通过下面会变成0 for(l=k;l<=n+1;++l){ ma[j][l]=ma[i][l]*tmp-ma[j][l]*ma[i][k]; ma[j][l]=(ma[j][l]%7+7)%7; } } ++num; ++k; } sum=0; for(i=num+1;i<=m;++i) //找是否会无解 if(ma[i][n+1]) return 0; if(num!=n) //多解 return 1; for(i=n;i;--i){ //唯一解 for(j=i+1;j<=n;++j){ ma[i][n+1]=ma[i][n+1]-arr[j]*ma[i][j]; ma[i][n+1]=(ma[i][n+1]%7+7)%7; } arr[i]=0; for(j=3;j<=9;++j) if(ma[i][i]*j%7==ma[i][n+1]) arr[i]=j; } return 2; } int main(){ ios::sync_with_stdio(0); mp["MON"]=1; mp["TUE"]=2; mp["WED"]=3; mp["THU"]=4; mp["FRI"]=5; mp["SAT"]=6; mp["SUN"]=7; while(cin>>n>>m,n+m){ int k,x; string s1,s2; memset(ma,0,sizeof ma); for(int i=1;i<=m;++i){ cin>>k; cin>>s1>>s2; ma[i][n+1]=(mp[s2]-mp[s1]+1+7)%7; while(k--){ cin>>x; ma[i][x]++; ma[i][x]%=7; } } ans=solve(); if(ans==0) cout<<"Inconsistent data."<<endl; else if(ans==1) cout<<"Multiple solutions."<<endl; else for(int i=1;i<=n;++i) cout<<arr[i]<<" \n"[i==n]; } return 0; }
以上是关于POJ2947-Widget Factory的主要内容,如果未能解决你的问题,请参考以下文章
POJ 2947-Widget Factory(高斯消元解同余方程式)