Widget Factory

Widget Factory

有N种零件,生产所需天数都为3~9天,有M条记录,记录开工星期几,和停工星期几,并告诉你这条记录所加工的零件,求每种零件的生产时间,\(1≤N,M≤300\)

显然可以对于一条记录列出关于x的方程(设t为从开工到停工的最短时间,\(\{a_i\}\)表示每个零件的生产时间,\(\{b_i\}\)表示每个零件加工的多少)

\[b_1a_1+...+b_na_n=7x+t \]

自然对于每个方程都有x这个未知数,没办法解,但是x前的系数都是7,考虑同余高斯消元,于是有

\[b_1a_1+...+b_na_n=t(mod\ 7) \]

对于每条记录,列出这样的方程,你可以根据lcm来消元,也可以通过逆元来消元,最好选择以已解方程个数作为高斯消元的主体,剩下的与套路无疑。

参考代码:

#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#define il inline
#define ri register
#define swap(x,y) x^=y^=x^=y
using namespace std;
int inv[8],jz[301][301],dis[8][8];
map<string,int>day;
il void mod(int&);
int main(){
    inv[1]=1,day["MON"]=1,day["TUE"]=2,day["WED"]=3;
    day["THU"]=4,day["FRI"]=5,day["SAT"]=6,day["SUN"]=7;
    int n,m,i,j,k;
    for(i=2;i<7;++i)inv[i]=-inv[7%i]*(7/i)%7,mod(inv[i]);
    for(i=1;i<=7;++i){
        dis[i][i]=1;
        for(j=i+1;j<=7;++j)
            dis[i][j]=j-i+1,dis[j][i]=9-dis[i][j];
    }
    while(scanf("%d%d",&n,&m),n&&m){
        memset(jz,0,sizeof(jz));
        for(i=1;i<=m;++i){
            char s[4],t[4];
            scanf("%d%s%s",&k,s,t);
            jz[i][0]=dis[day[s]][day[t]];
            while(k--)scanf("%d",&j),++jz[i][j];
            for(j=0;j<=n;++j)jz[i][j]%=7;
        }int w(0);
        for(i=1;i<=n;++i){
            for(j=w+1;j<=m;++j)
                if(jz[j][i])break;if(j>m)continue;++w;
            if(j!=w)for(k=0;k<=n;++k)swap(jz[w][k],jz[j][k]);
            (jz[w][0]*=inv[jz[w][i]])%=7;
            for(j=n;j>=i;--j)(jz[w][j]*=inv[jz[w][i]])%=7;
            for(j=1;j<=m;++j){
                if(!jz[j][i]||w==j)continue;
                mod(jz[j][0]-=jz[w][0]*jz[j][i]);
                for(k=n;k>=i;--k)
                    mod(jz[j][k]-=jz[j][i]*jz[w][k]);
            }
        }
        for(i=w+1;i<=m;++i)
             if(jz[i][0]){puts("Inconsistent data.");break;}
        if(i<=m)continue;
        if(w<n)puts("Multiple solutions.");
        else{
            mod(jz[i][0]),mod(jz[i][i]);
            for(i=1;i<=n;++i)
                if(jz[i][0]<3)printf("%d ",jz[i][0]+7);
                else printf("%d ",jz[i][0]);putchar('\n');
        }
    }
    return 0;
}
il void mod(int &x){
    ((x%=7)+=7)%=7;
}

posted @ 2019-05-18 22:27  a1b3c7d9  阅读(122)  评论(1编辑  收藏  举报