POJ2947 DAZE [Gauss]
2017-05-13 08:23 tlnshuju 阅读(195) 评论(0) 编辑 收藏 举报题目是要求建立一个方程组:
(mat[1][1]*x[1] + mat[1][2]*x[2] + … + mat[1][n]*x[n])%7 =mat[1][n+1]
(mat[2][1]*x[1] + mat[2][2]*x[2] + … + mat[2][n]*x[n])%7 =mat[2][n+1]
…
…
(mat[m][1]*x[1] + mat[m][2]*x[2] + … + mat[m][n]*x[n])%7 =mat[m][n+1]
假设有解输出解得个数。假设无解Inconsistent data.无穷多组解Multiple solutions.
扯一句,什么时候无解?
系数矩阵的秩 不等于 增广矩阵的秩 时。反映在程序上就是:
for (i = row; i < N; i++)
{
if (a[i][M] != 0)
{
printf("Inconsistent data.\n");
}
}
什么时候无穷多解?
当增广矩阵的秩小于行列式的行数的时候。 反映在程序上就是:
if (row < M)
{
printf("Multiple solutions.\n");
}
好了。程序例如以下:
#include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> using namespace std; int m,n;//n lines int M,N; int a[333][333]; int times[333]; int ans[333]; int MOD=7; int getday(char* s) { if(strcmp(s,"MON")==0) return 1; if(strcmp(s,"TUE")==0) return 2; if(strcmp(s,"WED")==0) return 3; if(strcmp(s,"THU")==0) return 4; if(strcmp(s,"FRI")==0) return 5; if(strcmp(s,"SAT")==0) return 6; if(strcmp(s,"SUN")==0) return 7; } int extend_gcd(int A, int B, int &x, int &y) { if (B == 0) { x = 1, y = 0; return A; } else { int r = extend_gcd(B, A%B, x, y); int t = x; x = y; y = t - A / B*y; return r; } } int lcm(int A, int B) { int x = 0, y = 0; return A*B / extend_gcd(A, B, x, y); } void Guass() { int i, j, row, col; for (row = 0, col = 0; row < N && col < M; row++, col++) { for (i = row; i < N; i++) if (a[i][col]) break; if (i == N) { row--; continue; } if (i != row) for (j = 0; j <= M; j++) swap(a[row][j], a[i][j]); for (i = row + 1; i < N; i++) { if (a[i][col]) { int LCM = lcm(a[row][col], a[i][col]);//利用最小公倍数去化上三角 int ch1 = LCM / a[row][col], ch2 = LCM / a[i][col]; for (j = col; j <= M; j++) a[i][j] = ((a[i][j] * ch2 - a[row][j] * ch1)%MOD + MOD)%MOD; } } } for (i = row; i < N; i++)//无解 { if (a[i][M] != 0) { printf("Inconsistent data.\n"); return; } } if (row < M)//无穷多解 { printf("Multiple solutions.\n"); return; } //唯一解时 for (i = M - 1; i >= 0; i--) { int ch = 0; for (j = i + 1; j < M; j++) { ch = (ch + ans[j] * a[i][j] % MOD)%MOD; } int last = ((a[i][M] - ch)%MOD + MOD)%MOD; int x = 0, y = 0; int d = extend_gcd(a[i][i], MOD, x, y); x %= MOD; if (x < 0) x += MOD; ans[i] = last*x / d%MOD; if (ans[i] < 3) ans[i] += 7; } for (int i = 0; i < M; i++) { if (i == 0) printf("%d", ans[i]); else printf(" %d", ans[i]); } printf("\n"); } int main() { while(scanf("%d%d",&m,&n)!=EOF) { if(m==0&&n==0) break; M=m,N=n; memset(a,0,sizeof(a)); memset(times,0,sizeof(times)); memset(ans,0,sizeof(ans)); for(int i=0;i<n;i++) { int prodnum;char str1[11],str2[11]; scanf("%d%s%s",&prodnum,str1,str2); for(int j=0;j<prodnum;j++) { int tmp; scanf("%d",&tmp); a[i][tmp-1]++; a[i][tmp-1]%=MOD; } a[i][m]=(getday(str2)-getday(str1)+1+MOD)%MOD; } Guass(); } return 0; }