[POJ2947] Widget Factory && 高斯消元

通过每个人列方程 把系数模7来防止溢出 最后除法的时候用逆元算一下

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<map>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 300;
inline int abs(int x) { return x > 0 ? x : -x; }
inline int gcd(int a, int b)  
{  
    while(b)  
    { int r = a % b; a = b; b = r; }  
    return a;  
}
inline int lcm(int a, int b)
{
    return a / gcd(a, b) * b;
}
int Ans[MAXN+10];
int Niyuan[] = { 0, 1, 4, 5, 2, 3, 6 };
char s[10], ss[10];
template <int maxn, int maxm>
struct Maxtrix{
    int equ, var;
    int A[maxn+10][maxm+10];
    void init() { memset(A, 0, sizeof(A)); equ = var = 0; }
    int Gauss(int equ, int var) {
        int row, col;
        for(row = 0, col = 0; row < equ && col < var; row++, col++)
        {
            int r = row;
            for(int i = row+1; i < equ;i++)
                if(abs(A[i][col]) > abs(A[r][col]))
                    r = i;
            if(A[r][col] == 0) {
                row--;
                continue;
            }
            if(r != row) for(int i = 0; i <= var; i++) swap(A[r][i], A[row][i]);
            for(int i = row+1; i < equ; i++)
            {
                if(!A[i][col]) continue;
                int LCM = lcm(abs(A[row][col]), abs(A[i][col]));
                int ta = LCM / abs(A[i][col]);
                int tb = LCM / abs(A[row][col]);
                if(A[row][col] * A[i][col] < 0) tb = -tb;
                for(int j = col; j <= var; j++)
                    A[i][j] = ((A[i][j] * ta - A[row][j] * tb) % 7 + 7) % 7;
            }
        }
        for(int i = row; i < equ; i++) 
            if(A[i][var]) 
                return -1;
        if(row < var) return 1;
        for(int i = var-1; i >= 0; i--)
        {
            int tmp = A[i][var];
            for(int j = i+1; j < var;j++)
                if(A[i][j] != 0)
                    tmp = ((tmp - A[i][j] * Ans[j]) % 7 + 7) % 7;
            Ans[i] = (tmp * Niyuan[A[i][i]]) % 7;
        }
        return 0;
    }
};
Maxtrix <MAXN, MAXN> A;
int Num(char s[])
{
    if(strcmp(s,"MON") == 0) return 1;
    else if(strcmp(s,"TUE")==0) return 2;
    else if(strcmp(s,"WED")==0) return 3;
    else if(strcmp(s,"THU")==0) return 4;
    else if(strcmp(s,"FRI")==0) return 5;
    else if(strcmp(s,"SAT")==0) return 6;
    else return 7;
}
int main()
{
    int n, m;
    while(SF("%d%d", &n, &m) == 2 && (n || m))
    {
        memset(A.A, 0, sizeof(A.A)); A.equ = m; A.var = n;
        for(int i = 0; i < m; i++)
        {
            int k;
            SF("%d%s%s", &k, s, ss);
            int u = Num(s), v = Num(ss);
            A.A[i][n] = ((v - u + 1) % 7 + 7) % 7;
            for(int j = 1; j <= k; j++)
            {
                SF("%d", &u); u--;
                A.A[i][u] = (A.A[i][u] + 1) % 7;
            }
        }
        int ans = A.Gauss(m, n);
        if(ans == 0) {
            for(int i = 0; i < n; i++) if(Ans[i] <= 2) Ans[i] += 7;
            for(int i = 0; i < n; i++)
                if(i == n-1) PF("%d\n", Ans[i]);
                else PF("%d ", Ans[i]);
        }
        else if(ans == -1) PF("Inconsistent data.\n");
        else PF("Multiple solutions.\n");
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值