题目大意:n种零件,m次工作日程,零件序号从1到n,给出m次工作日程的信息,x,s,e,表示生产了x个零件,从星期s开始到星期e(有可能是多个星期),然后给出生产的x个零件的序号。求每个零件被生产需要多少天(保证在3到10天)
解题思路:设未知数,列方程,高斯消元。
注意:要用整数高斯消元,消元时要取模加7再取模,防止负数(WA×1),输入的时候要取模(WA×2)。。。
代码:
using std::swap;
const int weekdays=7;
const char weekday[7][5]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
int getDay(char *s)
{
int i;
for(i=0;i<7&&strcmp(s,weekday[i])!=0;i++);
return i+1;
}
int n,m;
int A[MAXN][MAXN],finalR;
int gcd(int a,int b)
{
int t;
while(b)
{
t=a%b;
a=b;
b=t;
}
return a;
}
int lcm(int a,int b)
{return a/gcd(a,b)*b;}
int pow_mod(int a,int b,int p)
{
int ret=1;
for(;b;b>>=1,a=(a*a)%p)
if(b&1)
ret=(ret*a)%p;
return ret;
}
int inv(int a,int p)
{return pow_mod(a,p-2,p);}
void Init()
{
memset(A,0,sizeof A);
int k,i,j,id;
char s[5],e[5];
for(i=1;i<=m;i++)
{
scanf("%d%s%s",&k,s,e);
A[i][n+1]=(getDay(e)-getDay(s)+1+weekdays)%weekdays;
for(j=1;j<=k;j++)
{
scanf("%d",&id);
A[i][id]++;
A[i][id]%=weekdays;
}
}
}
void Gauss()
{
int r,c,t,i,j,l,ta,tb;
for(r=1,c=1;r<=m&&c<=n;r++,c++)
{
for(t=r;!A[t][c]&&t<=m;t++);
if(!A[t][c]){r--;continue;}
if(t!=r)swap(A[t],A[r]);
for(i=1;i<=m;i++)
if(i!=r&&A[i][c])
{
l=lcm(A[i][c],A[r][c]);
ta=l/A[i][c];
tb=l/A[r][c];
for(j=1;j<=n+1;j++)
A[i][j]=((A[i][j]*ta-A[r][j]*tb)%weekdays+weekdays)%weekdays;
}
}
finalR=r-1;
}
void Check()
{
int i;
for(i=finalR+1;i<=m;i++)
if(A[i][n+1])
{
printf("Inconsistent data.
");
return;
}
if(finalRprintf("Multiple solutions.
");
return;
}
int ans;
for(int i=1;i1]*inv(A[i][i],weekdays)%weekdays;
if(ans<3)ans+=weekdays;
printf("%d ",ans);
}
ans=A[n][n+1]*inv(A[n][n],weekdays)%weekdays;
if(ans<3)ans+=weekdays;
printf("%d
",ans);
}
int main()
{
while(1)
{
scanf("%d%d",&n,&m);
if(!n&&!m)break;
Init();
Gauss();
Check();
}
return 0;
}