题目链接:点击打开链接
题目大意:有n种零件,已知每种零件的加工时间最少为3天最多为9天,现在只知道有m个工程用的时间和加工的零件数,问可不可以求出每种零件的加工时间。
列出对7取余的m个方程,用高斯消元判断是否有解,并解出来。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#pragma comment(linker,"/STACK:102400000,102400000") ;
int Map[310][310] , a[310] ;
char str[8][10] = { "S","MON","TUE","WED","THU","FRI","SAT","SUN" } ;
char s1[10] , s2[10] ;
int n , m , ans[310] ;
int solve() {
int i , j , k = 1 , l , temp , num = 0 , sum ;
for(i = 1 ; i <= m && k <= n ; i++) {
for(j = i ; j <= m ; j++)
if( Map[j][k] ) break ;
if( j > m ) {
k++ ; i-- ;
continue ;
}
if( j != i ) {
for(l = k ; l <= n ; l++)
swap(Map[i][l],Map[j][l]) ;
swap(a[i],a[j]) ;
}
for(j = i+1 ; j <= m ; j++) {
if( !Map[j][k] ) continue ;
temp = Map[j][k] ;
for(l = k ; l <= n ; l++) {
Map[j][l] = Map[i][l]*temp - Map[j][l]*Map[i][k] ;
Map[j][l] = (Map[j][l]%7 + 7) % 7 ;
}
a[j] = a[i]*temp - a[j]*Map[i][k] ;
a[j] = (a[j]%7+7)%7 ;
}
num++ ;
k++ ;
}
sum = 0 ;
for(i = num+1 ; i <= m ; i++)
if( a[i] ) return 0 ;
if( num != n ) return 1 ;
for(i = n ; i >= 1 ; i--) {
for(j = i+1 ; j <= n ; j++){
a[i] = a[i]-ans[j]*Map[i][j] ;
a[i] = (a[i]%7+7)%7 ;
}
ans[i] = 0 ;
for(j = 3 ; j <= 9 ; j++) {
if( Map[i][i]*j%7 == a[i] )
ans[i] = j ;
}
//if( !ans[i] ) return 0 ;
}
return 2 ;
}
int main() {
int num , i , j , k1 , k2 , x ;
while( scanf("%d %d", &n, &m) && n+m ) {
memset(Map,0,sizeof(Map)) ;
for(i = 1 ; i <= m ; i++) {
scanf("%d %s %s", &num, s1, s2) ;
for(j = 1 ; j <= 7 ; j++) {
if( !strcmp(str[j],s1) ) k1 = j ;
if( !strcmp(str[j],s2) ) k2 = j ;
}
a[i] = (k2-k1+1+7)%7 ;
while( num-- ) {
scanf("%d", &x) ;
Map[i][x] = (Map[i][x]+1)%7 ;
}
}
k1 = solve() ;
if( k1 == 0 )
printf("Inconsistent data.\n") ;
else if( k1 == 1 )
printf("Multiple solutions.\n") ;
else {
for(i = 1 ; i < n ; i++)
printf("%d ", ans[i]) ;
printf("%d\n", ans[n]) ;
}
}
return 0 ;
}