POJ2947 Widget Factory [高斯消元]

Widget  Factorymathcal{Widget Factory}


Descriptionmathcal{Description}

存在 NN 种零件, 加工 ii 零件需要 costicost_i 的时间, 且 costicost_i 未知; 现给出 MM 条信息, 每条信息包括一个工人的 聘用时刻解雇时刻, 其加工了 KK个零件. 时刻都以 X   (X[1,7])星期X (X∈[1,7]) 来表示, 无具体日期.

请求出所有 costicost_i .
若无解输出 Inconsistent data.
若多解输出 Multiple solutions.

K<=10000, N,M<=300


Solutionmathcal{Solution}

列出 MMmod 7mod 7 的同余方程 .

For  example:For example:


a1,1x1+a1,2x2+...+a1,nxn5      (mod  7)a_{1,1}x_1+a_{1,2}x_2+...+a_{1,n}x_n equiv 5 (mod 7)
高斯消元后若得出 上三角矩阵, 则对最后一行进行分析 :
bb 为常数,
am,nxnb      (mod  7) am,nxn+7y=ba_{m,n}x_n equiv b (mod 7)\ \ a_{m,n}x_n +7y = b

使用 Ex_gcdEx\_gcd 求出 xnx_n, 回带到前一个方程
am1,n1xn1+am1,nxnb2      (mod  7)a_{m-1,n-1}x_{n-1}+a_{m-1,n}x_n equiv b_2 (mod 7)

此时将 xnx_n 项移动到右边, 又可以采用 Ex_gcdEx\_gcd 进行求解了.
于是不断 求解, 回带, 最后即可得出所有解.

注意高斯消元时不能产生小数, 所以要使用 LCMLCM 进行消元.


Codemathcal{Code}

Bug Code

#include<bits/stdc++.h>
#define reg register

int read(){
        char c;
        int s = 0, flag = 1;
        while((c=getchar()) && !isdigit(c))
                if(c == '-'){ c = getchar(), flag = -1; break; }
        while(isdigit(c)) s = s*10 + c-'0', c = getchar();
        return s * flag;
}

const int maxn = 305;

int FUCK;
int N;
int M;
int K;
int Ans[maxn];
int A[maxn][maxn];

std::string st;
std::string ed;

int Ex_gcd(int a, int b, int &x=FUCK, int &y=FUCK){
        if(!b){ x = 1, y = 0; return a; }
        int tmp = Ex_gcd(b, a%b, y, x);
        y -= (a/b) * x;
        return tmp;
}

int Trans(std::string s){
        if(s == "MON") return 1;
        else if(s == "TUE") return 2;
        else if(s == "WED") return 3;
        else if(s == "THU") return 4;
        else if(s == "FRI") return 5;
        else if(s == "SAT") return 6;
        return 7;
}

int Guass(){
        int t = 1;
        for(reg int i = 1; i <= N && t <= M; i ++, t ++){
                int max_id = 0;
                for(reg int j = t; j <= M; j ++)
                        if(A[j][i]){ max_id = j; break ; }
                if(!max_id){ t --; continue ; }
                if(max_id != t) std::swap(A[max_id], A[t]);
                for(reg int j = t+1; j <= M; j ++){
                        if(!A[j][i]) continue ;
                        int a = A[j][i], b = A[t][i];
                        int lcm = a/Ex_gcd(a, b) * b;
                        int tmp_1 = lcm/b, tmp_2 = lcm/a;
                       // printf("LCM: %d tmp_1: %d tmp_2: %d
", lcm, tmp_1, tmp_2);
                        for(reg int k = i; k <= N+1; k ++){
                                int &p = A[j][k];
                                p = p*tmp_2 - A[t][k]*tmp_1;
                                p = p%7 + 7;
                                if(p >= 7) p -= 7;
                        }
                }
        }

  //              printf("======= %d ====
", N-t+1);
        if(t <= N){
                for(reg int i = t; i <= N; i ++)
                        if(A[i][N+1]) return -1;  // No solution
                return 0;   // More than one solution
        }

        /*
        for(int i=1;i<=N;i++){

           for(int j=1;j<=N+1;j++) printf("%d ", A[i][j]);
           printf("
");
}
printf("=============
");
*/

        int y;
        for(reg int i = N; i >= 1; i --){ 
                int &p = A[i][N+1];
                for(reg int j = i+1; j <= N; j ++) p -= A[i][j] * Ans[j];
                p = (p%7 + 7) % 7;                
                
                int gcd = Ex_gcd(A[i][i], 7, Ans[i], y);
                Ans[i] *= p/gcd;
                Ans[i] = (Ans[i]%7 + 7) % 7;
                if(Ans[i] < 3) Ans[i] += 7;     //#
                
               /*
                for(reg int j = 3; j <= 9; j ++)
                        if(((A[i][i]*j%7)+7)%7 == A[i][N+1]){
                                Ans[i] = j;
                                break ;
                        }
                        */
        }
        return 1;
}

void Work(){ 
        memset(A, 0, sizeof A);
        for(reg int i = 1; i <= M; i ++){ 
                K = read(); 
                std::cin >> st >> ed;
                int t_1 = Trans(ed), t_2 = Trans(st);
                A[i][N+1] = ((t_1 - t_2 + 1)%7 + 7) % 7;
                while(K --){
                        A[i][A[i][0]=read()] ++;
                        if(A[i][A[i][0]] >= 7) A[i][A[i][0]] -= 7;
                }
        }

/*
        for(int i=1;i<=N;i++){

           for(int j=1;j<=N+1;j++) printf("%d ", A[i][j]);
           printf("
");
}
printf("=============
");
*/

        int flag = Guass();
        if(flag == -1) printf("Inconsistent data."); 
        else if(!flag) printf("Multiple solutions.");
        else for(reg int i = 1; i <= N; i ++) printf("%d ", Ans[i]);
        printf("
");
}

int main(){
        freopen("My.in", "r", stdin);
        freopen("My.out", "w", stdout);
        while((N = read()) && (M = read())) Work();
        return 0;
}




std

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MOD 7
using namespace std;
int m,n,matrix[310][310],ans[310];
int get_id(char s[])
{
    char week[8][5]={"","MON","TUE","WED","THU","FRI","SAT","SUN"};
    int i;
    for(i=1;i<=7;i++)
        if(strcmp(s,week[i])==0)
            break;
    return i;
}
int ex_gcd(int a,int b,int &x,int &y)
{
    int t,d;
    if(b==0){
        x=1;
        y=0;
        return a;
    }
    d=ex_gcd(b,a%b,x,y);
    t=x;
    x=y;
    y=t-a/b*y;
    return d;
}
int Lcm(int a,int b)
{
    int x,y;
    return a*b/ex_gcd(a,b,x,y);
}
int guass()
{
    int i,j,row,col;
    for(row=0,col=0;row<n&&col<m;row++,col++){
        for(i=row;i<n;i++)
            if(matrix[i][col])
                break;
        if(i==n){          //col列全为0
            row--;
            continue;
        }
        if(i!=row)
            for(j=0;j<=m;j++)
                swap(matrix[row][j],matrix[i][j]);   //交换两行
        for(i=row+1;i<n;i++){          
            if(matrix[i][col]){
                int lcm=Lcm(matrix[row][col],matrix[i][col]);
                int t1=lcm/matrix[i][col],t2=lcm/matrix[row][col];
                printf("LCM: %d tmp_1: %d tmp_2: %d
", lcm, t1, t2);
                for(j=col;j<=m;j++)
                    matrix[i][j]=((matrix[i][j]*t1-matrix[row][j]*t2)%MOD+MOD)%MOD;
            }
        }
    }
    printf("===== %d =====
", m-row);
    for(i=row;i<n;i++)     
        if(matrix[i][m])          //无解
            return -1;
    if(row<m)                    //有无穷解
        return 0;
        for(int i=0;i<m;i++){

           for(int j=0;j<=m;j++) printf("%d ", matrix[i][j]);
           printf("
");
}
printf("=============
");
    memset(ans,0,sizeof(ans));  //唯一解求解过程如下
    for(i=n-1;i>=0;i--){        
        int temp=0;
        for(j=i+1;j<m;j++)
            temp=(temp+matrix[i][j]*ans[j]%MOD)%MOD;
        int b=((matrix[i][m]-temp)%MOD+MOD)%MOD;
        int x,y;
        int d=ex_gcd(matrix[i][i],MOD,x,y);  //解模线性方程
        x=x*(b/d)%MOD;
        x=(x%(MOD/d)+(MOD/d))%(MOD/d);
        ans[i]=x;
        if(ans[i]<3)
            ans[i]+=7;
    }
    return 1;
}
int main()
{
        freopen("My.in", "r", stdin);
        freopen("std.out", "w", stdout);
    int num,i,j,type;
    char start[5],end[5];
    while(scanf("%d%d",&m,&n)!=EOF){
        if(m==0&&n==0) break;
        memset(matrix,0,sizeof(matrix));
        for(i=0;i<n;i++){
            scanf("%d%s%s",&num,start,end);
            matrix[i][m]=((get_id(end)-get_id(start)+1)%MOD+MOD)%MOD; //求生产时间对7取余
            for(j=1;j<=num;j++){
                scanf("%d",&type);
                matrix[i][type-1]=(matrix[i][type-1]+1)%MOD;   //记录矩阵的值
            }
        }

        for(i=0;i<m;i++){

           for(j=0;j<=m;j++) printf("%d ", matrix[i][j]);
           printf("
");
}
printf("=============
");


        int flag=guass();   //高斯消元
        if(flag==-1)
            printf("Inconsistent data.
");
        else if(flag==0)
            printf("Multiple solutions.
");
        else{
            for(i=0;i<m-1;i++)
                printf("%d ",ans[i]);
            printf("%d
",ans[m-1]);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/zbr162/p/11822579.html