poj2947--Widget Factory(高斯消元)

题目链接:点击打开链接

题目大意:有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 ;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值