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]<<" 
"[i==n];
    }
    return 0;
}
原文地址:https://www.cnblogs.com/-Chamgin/p/8979025.html