zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    velocity语法
    使用VS2003创建WEB程序的时候出现"AutoMation服务器不能创建对象"错误
    ASP.NET 2.0 Tips:跨页提交
    Tip #1 – 创建、管理、应用样式表的强大工具(Visual Studio 2008)
    解决ASP.NET2.0和1.1在同一台电脑上不能并行的问题
    Tip #2 - 样式应用工具(style application toolbar)
    利用HttpModuler实现WEB程序同一时间只让一个用户实例登陆
    ASP.NET Tips: 获取插入记录的ID
    通过rsync远程增量备份数据
    array_merge() [function.arraymerge]: Argument #1 is not an array in ……错误的解决办法
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822579.html
Copyright © 2011-2022 走看看