poj2947Widget Factory
对于同余方程的高斯消元啊。
其实也差不多吧。先同一位通分,然后减一下就好了。
主要是判无解和多解的麻烦,需要注意即使有自由元也可能先无解
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #define MOD(x) (x%7+7)%7 using namespace std; int n,m; char ss[10]; int scs() { scanf("%s",ss+1); if(ss[1]=='M')return 1; else if(ss[1]=='T'&&ss[2]=='U')return 2; else if(ss[1]=='W')return 3; else if(ss[1]=='T')return 4; else if(ss[1]=='F')return 5; else if(ss[1]=='S'&&ss[2]=='A')return 6; else return 7; } int gcd(int a,int b) { if(a==0)return b; return gcd(b%a,a); } int exgcd(int a,int b,int &x,int &y) { if(a==0) { x=0,y=1; return b; } else { int tx,ty; int d=exgcd(b%a,a,tx,ty); x=ty-b/a*tx; y=tx; return d; } } int qg[310][310],qc[310]; int as[310]; void gauss() { int j,jj; for(j=1,jj=1;j<=n&&jj<=m;j++) { for(int i=jj;i<=m;i++) if(qg[i][j]!=0) { for(int k=j;k<=n;k++)swap(qg[i][k],qg[jj][k]); swap(qc[i],qc[jj]); break; } if(qg[jj][j]==0)continue; for(int i=1;i<=m;i++) { if(i==jj)continue; int gg=gcd(qg[i][j],qg[jj][j]); int ml1=qg[jj][j]/gg,ml2=qg[i][j]/gg; for(int k=1;k<=n;k++) qg[i][k]=MOD(qg[i][k]*ml1-qg[jj][k]*ml2); qc[i]=MOD(qc[i]*ml1-qc[jj]*ml2); } jj++; } for(int i=jj;i<=m;i++) if(qc[i]>0){printf("Inconsistent data.\n");return ;} if(jj!=j||j<=n){printf("Multiple solutions.\n");return ;} for(int j=1;j<=n;j++) { int A=qg[j][j],B=7,K=qc[j],x,y; int d=exgcd(A,B,x,y); x=(x*(K/d)%(B/d)+(B/d))%(B/d); if(x<3)x+=7; as[j]=x; } for(int j=1;j<n;j++)printf("%d ",as[j]); printf("%d\n",as[n]); } int v[310]; int main() { while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0)break; for(int i=1;i<=m;i++) { int k,x; scanf("%d",&k);int s1=scs(),s2=scs(); qc[i]=MOD(s2-s1+1); memset(v,0,sizeof(v)); for(int j=1;j<=k;j++) scanf("%d",&x), v[x]++; for(int j=1;j<=n;j++)qg[i][j]=MOD(v[j]); } gauss(); } return 0; }
pain and happy in the cruel world.