POJ - 2947 Widget Factory(同余式的高斯消元)

题目链接

ACCode:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 310;
int mod;
int Equ, Var;      //方程式的个数, 未知数的个数
int A[maxn][maxn]; //增广矩阵,最后一列是系数
int X[maxn];       //存储所有的解
bool FreeX[maxn];
int FreeNum;       //自由元的个数

int GCD(int a, int b)
{
    if(b == 0)
        return a;
    else
        return GCD(b, a%b);
}
int LCM(int a, int b)
{
    return a/GCD(a, b) * b;
}

void ex_gcd(int a, int b, int& d, int& x, int& y) //扩展欧几里得求贝祖等式
{
    if(!b){
        d = a; x = 1; y = 0;
    }
    else{
        ex_gcd(b, a%b, d, y, x);
        y -= x*(a/b);
    }
}
//高斯消元主方程
int Gauss_Elimination()
{
    int i, j, k;
    int MaxRow;
    int col = 0;
    int Lcm;
    int ta, tb;
    int temp;
    int FreeXNum, FreeIndex;
    for(int i = 0; i < Var; i++){
        X[i] = 0; FreeX[i] = true;
    }
    for(k = 0; k < Equ && col < Var; k++, col++){
        MaxRow = k;
        for(i = k+1; i < Equ; i++){
            if(abs(A[i][col]) > abs(A[MaxRow][col]))
                MaxRow = i;
        }
        if(MaxRow != k){
            for(j = k; j <= Var; j++)
                swap(A[k][j], A[MaxRow][j]);
        }
        if(A[k][col] == 0){
            k --;
            continue;
        }
        for(i = k+1; i < Equ; i++){
            if(A[i][col]){
                Lcm = LCM(abs(A[i][col]), abs(A[k][col]));
                ta = Lcm / abs(A[i][col]);
                tb = Lcm / abs(A[k][col]);
                if(A[i][col] * A[k][col] < 0) tb = -tb;
                for(j = col; j <= Var; j++)
                    A[i][j] = (A[i][j]*ta%mod - A[k][j]*tb%mod + mod) % mod;
            }
        }
    }
//已经化成阶梯型矩阵了
    for(i = k; i < Equ; i++)
        if(A[i][col]) return -1;  //存在 0 0 0 3 这样的情况,无解
    if(k < Var)                   //存在 0 0 0 0 这样的情况,有多解
        return Var-k;             //返回自由元的个数

    // 回代
    for(int i = Var-1; i >= 0; i--){
        for(int j = i+1; j < Var; j++){
            A[i][Var] -= ((X[j] * A[i][j]) % mod);
        }
        A[i][Var] = (A[i][Var]%mod + mod) % mod;
        int x, y, d;
        ex_gcd(A[i][i], mod, d, x, y);
        X[i] = (A[i][Var]*x% mod + mod) % mod;
    }
    return 0;
}
char Wed[7][5] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" };
int get_id(char *str)
{
    for(int i = 0; i < 7; i++)
        if(!strcmp(Wed[i], str))
            return i;
}

int main()
{
    int num, dur, x;
    char s1[50], s2[50];
    while(scanf("%d %d", &Var, &Equ) && (Var+Equ)){
        memset(A, 0, sizeof(A));
        mod = 7;
        for(int i = 0; i < Equ; i++){
            scanf("%d %s %s", &num, s1, s2);
            int be = get_id(s1), ed = get_id(s2);
            if(be > ed) dur = ed + mod+1 - be;
            else        dur = ed - be + 1;
            A[i][Var] = dur;
            while(num--){
                scanf("%d", &x);
                A[i][x-1] ++;
                A[i][x-1] %= mod;
            }
        }
        int ans = Gauss_Elimination();
        if(ans == -1)    cout << "Inconsistent data." << endl;
        else if(ans > 0) cout << "Multiple solutions." << endl;
        else {
            for(int i = 0; i < Var; i++){
                if(X[i] < 3) X[i] += mod;
                if(X[i] > 9){
                    X[i] %= 7;
                    if(X[i] < 3) X[i] += mod;
                }
                if(i == 0) cout << X[i];
                else       cout << " " << X[i];
            } cout << endl;
        }
    }
    return 0;
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值