POJ 2947 Widget Factory 高斯消元 解线性同余方程

时空隧道


题意:
有n种工作,m个人,每个人在某段时间中完成k个任务,求出n个任务的单个完成时间…(每个任务完成时间在[3,7]区间中)…
如果无解输出Inconsistent data.
如果有无穷多个解输出Inconsistent data.


分析:
很容易就可以得出方程….然后消元就好了…


代码如下:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
//by NeighThorn
using namespace std;
const int maxn=300+5,MOD=7;
int n,m,coe[maxn][maxn];
map<string,int> mp;
string str[2];
inline int gauss(void){
    int i,j;
    for(i=1,j=1;i<=m&&j<=n;j++){//i枚举第几个方程,j枚举第几个主元 
        int k=i;
        while(!coe[k][j]&&k<=m)
            k++;
        if(coe[k][j]){//消元 
            for(int s=1;s<=n+1;s++)
                swap(coe[k][s],coe[i][s]);
            for(int l=i+1;l<=m;l++)
                if(coe[l][j]){
                    int x=coe[i][j],y=coe[l][j];
                    for(int s=j;s<=n+1;s++)
                        coe[l][s]=((coe[l][s]*x-coe[i][s]*y)%MOD+MOD)%MOD;
                }
            i++;
        }
    }
    for(int x=i;x<=m;x++)
        if(coe[x][n+1])
            return -1;
    if(i<=n)
        return n-i+1;
    for(int x=n;x>=1;x--){
        for(int y=x+1;y<=n;y++)
            if(coe[x][y])
                coe[x][n+1]=((coe[x][n+1]-(coe[y][n+1]*coe[x][y]%MOD))%MOD+MOD)%MOD;
        while(coe[x][n+1]%coe[x][x]!=0)
            coe[x][n+1]+=MOD;
        coe[x][n+1]=(coe[x][n+1]/coe[x][x])%MOD;
    }
    return 0;
}
signed main(void){
    mp["MON"]=1,mp["TUE"]=2,mp["WED"]=3,mp["THU"]=4,mp["FRI"]=5,mp["SAT"]=6,mp["SUN"]=7;
    while(scanf("%d%d",&n,&m)&&!(!n&&!m)){
        memset(coe,0,sizeof(coe));
        for(int i=1,num;i<=m;i++){
            cin>>num>>str[0]>>str[1];
            coe[i][n+1]=(mp[str[1]]-mp[str[0]]+1+7)%7;
            for(int j=1,x;j<=num;j++)
                scanf("%d",&x),coe[i][x]++;
            for(int j=1;j<=n;j++)
                coe[i][j]%=7;
        }
        int lala=gauss();
        if(lala==-1)
            puts("Inconsistent data.");//没有解 
        else if(lala)
            puts("Multiple solutions.");//无穷解 
        else{
            for(int i=1;i<=n;i++)
                if(coe[i][n+1]<3)
                    coe[i][n+1]+=7;
            for(int i=1;i<n;i++)
                printf("%d ",coe[i][n+1]);
            printf("%d\n",coe[n][n+1]);
        }
    }
    return 0;
}

by >_< NeighThorn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值