POJ 2947 Widget Factory
题意:
有n种饰品,每种的加工时间为3~9天,现在知道m条记录,每条记录形如:开始时间是周几,终止时间是周几,加工出来哪些饰品,各多少件。但是不知道持续了多少周。
求每种饰品的加工时间。
需要判断无解和多解。
昨天晚上做到12:20....
显然是裸的同余方程组
无解?和异或方程组一样
多解?
异或方程组用的是高斯约当消元记录now很方便,同余方程高斯消元需要回代怎么办?于是我想到记录一个$pivot[i]$表示第i个方程的关键元,回代什么的用pivot[i]就行了
[update 11:21:16]
昨天晚上思维太混乱了现在看看写的有问题
于是仔细的想了一下:
在消元之后回代之前就可以判断无解和多解啦
进行回代时保证是唯一解
网上的题解太扯了还要什么复制到最后....
然后输入的时候别忘$mod \ 7$
516ms好快啊
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int N=305; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } typedef int Matrix[N][N]; int n,m,P=7; char s1[5],s2[5]; Matrix a; int mp[300]; inline int num(char *s){ if(s[0]=='T') return s[1]=='U'?1:3; else if(s[0]=='S') return s[1]=='A'?5:6; else return mp[s[0]]; } int inv[10]; void iniInv(){ inv[1]=1; for(int i=2;i<=P;i++) inv[i]=(-P/i*inv[P%i]%P+P)%P; } int now; void Gauss(){ now=1; for(int i=1;i<=n;i++){ int j=now; while(j<=m&&!a[j][i]) j++; if(j==m+1) continue; //printf("hi %d %d %d\n",i,now,j); if(j!=now) for(int k=1;k<=n+1;k++) swap(a[now][k],a[j][k]); for(int j=now+1;j<=m;j++) if(a[j][i]){//printf("jjj %d\n",j); int t=a[j][i]*inv[a[now][i]]%P;//printf("t %d\n",t); for(int k=i;k<=n+1;k++) a[j][k]=(a[j][k]-a[now][k]*t%P+P)%P; } now++; } for(int i=1;i<=m;i++) if(a[i][n+1]){ int f=0; for(int j=1;j<=n;j++) if(a[i][j]){f=1;break;} if(f==0) {puts("Inconsistent data.");return;} } if(now<n) {puts("Multiple solutions.");return;} for(int i=m;i>=1;i--){ for(int j=m;j>i;j--) a[i][n+1]=(a[i][n+1]-a[i][j]*a[j][n+1]%P+P)%P; a[i][n+1]=a[i][n+1]*inv[a[i][i]]%P; } for(int i=1;i<=n;i++) printf("%d%c",a[i][n+1]<3?a[i][n+1]+P:a[i][n+1],i==n?'\n':' '); } void solve(){ //printf("now %d\n",now); //for(int i=1;i<=m;i++) //for(int j=1;j<=n+1;j++) printf("%d%c",a[i][j],j==n+1?'\n':' '); } inline void ini(){memset(a,0,sizeof(a));} int main(){ freopen("in","r",stdin); mp['M']=0;mp['W']=2;mp['F']=4; iniInv(); while(true){ ini(); n=read();m=read(); if(n==0&&m==0) break; for(int i=1;i<=m;i++){ int k=read();scanf("%s%s",s1,s2); a[i][n+1]=(num(s2)-num(s1)+1+P)%P; while(k--) a[i][read()]++; for(int j=1;j<=n+1;j++) a[i][j]%=P; //printf("a %d\n",i); //for(int j=1;j<=n+1;j++) printf("%d%c",a[i][j],j==n+1?'\n':' '); } Gauss(); } }
Copyright:http://www.cnblogs.com/candy99/