题意:有 n 个零件,每个零件需要 [3,9] 内的其中一天完成,现给出 m 个工人开始开始和结束工作的日期(星期几) 还有它们加工的所有零件种类,求出每一种零件加工需要的时间;
分析:裸的高斯消元解同余线性方程组,套板子就行;
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
const int MOD = 7;
const int N = 300+5;
int a[N][N];
int x[N];
int n,m;
int Days(char s[]){
if(strcmp(s,"MON")==0) return 1;
if(strcmp(s,"TUE")==0) return 2;
if(strcmp(s,"WED")==0) return 3;
if(strcmp(s,"THU")==0) return 4;
if(strcmp(s,"FRI")==0) return 5;
if(strcmp(s,"SAT")==0) return 6;
if(strcmp(s,"SUN")==0) return 7;
}
int gcd(int a,int b){
if(a>b) swap(a,b);
if(b%a==0) return a;
return gcd(b%a,a);
}
int lcm(int a,int b){
return a/gcd(a,b)*b;
}
ll inv(ll a,ll m){
if(a==1) return 1;
return inv(m%a,m)*(m-m/a)%m;
}
int Gauss(int equ,int var){
int max_r,col,k;
for(k=0,col=0;k<equ&&col<var;k++,col++){
max_r=k;
for(int i=k+1;i<equ;i++)
if(abs(a[i][col])>abs(a[max_r][col]))
max_r=i;
if(a[max_r][col]==0){
k--;
continue;
}
if(max_r!=k)
for(int j=col;j<var+1;j++)
swap(a[k][j],a[max_r][j]);
for(int i=k+1;i<equ;i++){
if(a[i][col]!=0){
int LCM=lcm(abs(a[i][col]),abs(a[k][col]));
int ta=LCM/abs(a[i][col]);
int tb=LCM/abs(a[k][col]);
if(a[i][col]*a[k][col]<0) tb-=tb;
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta-a[k][j]*tb)%MOD+MOD)%MOD;
}
}
}
for(int i=k;i<equ;i++)
if(a[i][col]!=0)
return -1;
if(k<var) return var-k;
for(int i=var-1;i>=0;i--){
int temp=a[i][var];
for(int j=i+1;j<var;j++){
if(a[i][j]!=0){
temp-=a[i][j]*x[j];
temp=(temp%MOD+MOD)%MOD;
}
}
x[i]=(temp*inv(a[i][i],MOD))%MOD;
}
return 0;
}
int main()
{
while(~scanf("%d%d",&n,&m)&&n+m)
{
memset(a,0,sizeof(a));
char s1[3],s2[3];
for(int i=0,k;i<m;i++){
scanf("%d%s%s",&k,s1,s2);
a[i][n]=(Days(s2)-Days(s1)+1+MOD)%MOD;
while(k--){
int type; scanf("%d",&type);
type--;
a[i][type]++;
a[i][type]%=MOD;
}
}
int ans=Gauss(m,n);
if(ans==0){
for(int i=0;i<n;i++)
if(x[i]<3) x[i]+=7;
for(int i=0;i<n;i++)
printf("%d%c",x[i],i==n-1?'\n':' ');
}
else if(ans==-1) puts("Inconsistent data.");
else puts("Multiple solutions.");
}
}