题目:
题意:
有n 种装饰物,m 个已知条件,每个已知条件的描述如下:
p start end
a1,a2……ap (1<=ai<=n)
第一行表示从星期start 到星期end 一共生产了p件装饰物(工作的天数为end-start+1+7*x,加7*x 是因为它可能生产很多周),第二行表示这p 件装饰物的种类(可能出现相同的种类)。规定每件装饰物至少生产3 天,最多生产9 天。问每种装饰物需要生产的天数。
如果没有解,则输出“Inconsistent data.”,如果有多解,则输出“Multiple solutions.”,如果只有唯一解,则输出每种装饰物需要生产的天数。
题解:
这个样子列出同余方程用高斯消元去解应该不难了吧
因为m和n不相同,如果某一项的系数为0,不能成为i的关键方程,我们应该选择把他换到最后,因为ta有可能是别的人的关键方程
而且正因为m是累加的,我们要保证a和b的这些项为0,每次清零就是必不可少的
还有也不能像以前一样一看到这一项没有系数而且b为0就判断很多解了,因为好多方程等着判断呢,万一后边有个无解的情况怎么办
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int mod=7;
int a[305][305],b[305],ans[305],n,m;
int ksm(int a,int k)
{
int ans=1;
for (;k;k>>=1,a=a*a%mod)
if (k&1) ans=ans*a%mod;
return ans;
}
void gauss()
{
for (int i=1;i<=n;i++)
{
int num=i;
for (int j=i+1;j<=m;j++)
if (a[num][i]<a[j][i]) num=j;
if (num!=i)
{
for (int j=i;j<=n;j++)
swap(a[num][j],a[i][j]);
swap(b[num],b[i]);
}
else if (!a[i][i])
{
++m;
for (int j=i;j<=n;j++)
swap(a[num][j],a[m][j]);
swap(b[num],b[m]);
}
for (int j=i+1;j<=m;j++)
{
int t=a[j][i]*ksm(a[i][i],mod-2)%mod;
for (int k=i;k<=n;k++)
a[j][k]=(a[j][k]-a[i][k]*t%mod+mod)%mod;
b[j]=(b[j]-t*b[i]%mod+mod)%mod;
}
}
bool fff=0;
for (int i=n;i>=1;i--)
{
if (!a[i][i])
{
if (!b[i]) {fff=1;continue;}
else {printf("Inconsistent data.\n");return;}
}
ans[i]=b[i]*ksm(a[i][i],mod-2)%mod;
for (int j=1;j<i;j++)
b[j]=(b[j]-ans[i]*a[j][i]%mod+mod)%mod;
}
for (int i=n+1;i<=m;i++)
{
int now=0;
for (int j=1;j<=n;j++)
now=(now+ans[j]*a[i][j]%mod)%mod;
if (now!=b[i]) {printf("Inconsistent data.\n");return;}
}
if (fff) {printf("Multiple solutions.\n");return;}
for (int i=1;i<=n;i++)
{
if (ans[i]<=2) ans[i]+=mod;
printf("%d ",ans[i]);
// printf("%d%c",ans[i]," \n"[i==n]);
}
printf("\n");
}
int main()
{
char s[5],e[5];int x;
while (scanf("%d%d",&n,&m) && n!=0)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(ans,0,sizeof(ans));
for (int i=1;i<=m;i++)
{
int p,beg,en;scanf("%d",&p);scanf("%s",s);scanf("%s",e);
if (s[0]=='M') beg=1;
else if (s[0]=='W') beg=3;
else if (s[0]=='F') beg=5;
else if (s[0]=='T' && s[1]=='U') beg=2;
else if (s[0]=='T' && s[1]=='H') beg=4;
else if (s[0]=='S' && s[1]=='A') beg=6;
else if (s[0]=='S' && s[1]=='U') beg=7;
if (e[0]=='M') en=1;
else if (e[0]=='W') en=3;
else if (e[0]=='F') en=5;
else if (e[0]=='T' && e[1]=='U') en=2;
else if (e[0]=='T' && e[1]=='H') en=4;
else if (e[0]=='S' && e[1]=='A') en=6;
else if (e[0]=='S' && e[1]=='U') en=7;
b[i]=(en-beg+1+mod)%mod;
while (p--) scanf("%d",&x),a[i][x]++,a[i][x]%=mod;
}
gauss();
}
}