题意:
p start end
a1,a2......ap (1<=ai<=n)第一行表示从星期start 到星期end 一共生产了p 件装饰物(工作的天数为end-start+1+7*x,加7*x 是因为它可能生产很多周),第二行表示这p 件装饰物的种类(可能出现相同的种类,即ai=aj)。规定每件装饰物至少生产3 天,最多生产9 天。问每种装饰物需要生产的天数。如果没有解,则输出“Inconsistent data.”,如果有多解,则输出“Multiple solutions.”,如果只有唯一解,则输出每种装饰物需要生产的天数。 题解:
设每种装饰物需要生产的天数为xi(1<=i<=n)。每一个条件就相当于
给定了一个方程式,假设生产1 类装饰物a1 件、2 类装饰物a2 件、i 类装饰物ai 件所花费 的天数为b,则可以列出下列方程: a1*x1+a2*x2+...an*xn = b (mod 7) 这样一共可以列出m个方程式,然后使用高斯消元来解。
感觉高斯消元求解同模方程组跟线性方程组很像。
如果求出了一组解(x1,x2.....xn),则(x1+mod,x2+mod,.....,xn+mod)也是一组解。
必定有一组解是xi都<mod的。
所以就在加减的时候都要mod。然后还有不能直接除,要求逆元。
放个模版(n个方程,m-1个未知数),跟上题浮点数不一样,这题是整数,所以要求最小公倍数:
1 int gauss(int n,int m) 2 { 3 int i,j,k,l,r; 4 for(i=1,j=1;j<=maxx(n,m-1);j++) 5 { 6 r=i; 7 for(k=i+1;k<=n;k++) 8 if(myabs(a[k][j])>myabs(a[r][j])) r=k; 9 if(a[r][j])10 {11 for(l=1;l<=m;l++) swap(a[r][l],a[i][l]);12 for(l=i+1;l<=n;l++)13 {14 if(a[l][j])15 {16 int x=lcm(a[l][j],a[i][j]);17 int la=x/a[i][j];18 int lb=x/a[l][j];19 for(k=i;k<=m;k++)20 {21 a[l][k]=((a[l][k]*lb-a[i][k]*la)%mod+mod)%mod;22 }23 }24 }25 i++;26 }27 }28 // output(n,m);printf("i = %d\n",i);29 for(j=minn(i,m);j<=n;j++) 30 if(a[j][m]) return -1;//无解31 if((i-1)<(m-1)) return 0;//有无穷解32 //求解唯一解(不能除,求逆元)33 int b;34 for(i=m-1;i>=1;i--)35 {36 for(j=i+1;j
代码:我真的不知道为什么wa了。。拍了一百年了。。
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 9 const int N=350; 10 const int mod=7; 11 int a[N][N]; 12 char s1[10],s2[10]; 13 14 void output(int n,int m) 15 { 16 for(int i=1;i<=n;i++) 17 { 18 for(int j=1;j<=m;j++) 19 printf("%d ",a[i][j]); 20 printf("\n"); 21 } 22 printf("\n"); 23 } 24 25 int myabs(int x){ return x>0 ? x:-x;} 26 int minn(int x,int y){ return x y ? x:y;} 28 29 int idx(char s[]) 30 { 31 if(s[0]=='M') return 1; 32 if(s[0]=='T' && s[1]=='U') return 2; 33 if(s[0]=='W') return 3; 34 if(s[0]=='T' && s[1]=='H') return 4; 35 if(s[0]=='F') return 5; 36 if(s[0]=='S' && s[1]=='A') return 6; 37 return 7; 38 } 39 40 int gcd(int x,int y) 41 { 42 if(y==0) return x; 43 return gcd(y,x%y); 44 } 45 46 int quickpow(int x,int y,int mod) 47 { 48 int ans=1; 49 while(y) 50 { 51 if(y&1) ans=(ans*x)%mod; 52 x=x*x; 53 y/=2; 54 } 55 return ans; 56 } 57 58 int lcm(int x,int y) 59 { 60 if(!x && !y) return 0; 61 return x*y/gcd(x,y); 62 } 63 64 int gauss(int n,int m) 65 { 66 int i,j,k,l,r; 67 for(i=1,j=1;j<=maxx(n,m-1);j++) 68 { 69 r=i; 70 for(k=i+1;k<=n;k++) 71 if(myabs(a[k][j])>myabs(a[r][j])) r=k; 72 if(a[r][j]) 73 { 74 for(l=1;l<=m;l++) swap(a[r][l],a[i][l]); 75 for(l=i+1;l<=n;l++) 76 { 77 if(a[l][j]) 78 { 79 int x=lcm(a[l][j],a[i][j]); 80 int la=x/a[i][j]; 81 int lb=x/a[l][j]; 82 for(k=i;k<=m;k++) 83 { 84 a[l][k]=((a[l][k]*lb-a[i][k]*la)%mod+mod)%mod; 85 } 86 } 87 } 88 i++; 89 } 90 } 91 // output(n,m);printf("i = %d\n",i); 92 for(j=minn(i,m);j<=n;j++) 93 if(a[j][m]) return -1;//无解 94 if((i-1)<(m-1)) return 0;//有无穷解 95 //求解唯一解(不能除,求逆元) 96 int b; 97 for(i=m-1;i>=1;i--) 98 { 99 for(j=i+1;j