poj2947

高斯消元法模版题,但套模版没用。。

先回顾一下线性代数的知识。

若要求解如下方程:

poj2947

首先,其系数矩阵为

poj2947

然后,其增广矩阵为:

poj2947

然后若要求解这个方程,首先将第一行第一个元素化为1,即:第一行乘以1/3。

poj2947

然后将第二、三行减去第一行五倍:

poj2947

扯淡了不是。。太麻烦了。。。额,我不会告诉你我用matlab做的。。

a = [3,2,4; 5, 3, 1; 10, 2,2];

b = [10;1;3];

x = inv(a) * b;

x = a\b;

然后这个方程的解是-0.2059   -0.2500    2.7794。。。

好了废话少说。

题目是要求建立一个方程组:

(mat[1][1]*x[1] + mat[1][2]*x[2] + … + mat[1][n]*x[n])%7 =mat[1][n+1]

(mat[2][1]*x[1] + mat[2][2]*x[2] + … + mat[2][n]*x[n])%7 =mat[2][n+1]

(mat[m][1]*x[1] + mat[m][2]*x[2] + … + mat[m][n]*x[n])%7 =mat[m][n+1]

如果有解输出解得个数,如果无解Inconsistent data.无穷多组解Multiple solutions.


扯一句,什么时候无解?

系数矩阵的秩 不等于 增广矩阵的秩 时。反映在程序上就是:

for (i = row; i < N; i++)
{
if (a[i][M] != 0)
{
printf("Inconsistent data.\n");
}
}

什么时候无穷多解?

当增广矩阵的秩小于行列式的行数的时候。 反映在程序上就是:

if (row < M)
{
printf("Multiple solutions.\n");
}

好了,程序如下:

 

#include<iostream>
#include<cstdio>
#include<string.h>

using namespace std;

#define MOD 7

int a[310][310];
int N, M;
char str1[5], str2[5];
int ans[310];

int solved(char s [])
{
    if (s[0] == 'M'return 1;
    if (s[0] == 'T' && s[1] == 'U'return 2;
    if (s[0] == 'W'return 3;
    if (s[0] == 'T' && s[1] == 'H'return 4;
    if (s[0] == 'F'return 5;
    if (s[0] == 'S' && s[1] == 'A'return 6;
    if (s[0] == 'S' && s[1] == 'U'return 7;
}

int extend_gcd(int A, int B, int &x, int &y)
{
    if (B == 0)
    {
        x = 1, y = 0;
        return A;
    }
    else
    {
        int r = extend_gcd(B, A%B, x, y);
        int t = x;
        x = y;
        y = t - A / B*y;
        return r;
    }
}

int lcm(int A, int B)
{
    int x = 0, y = 0;
    return A*B / extend_gcd(A, B, x, y);
}

void Guass()
{
    int i, j, row, col;
    for (row = 0, col = 0; row < N && col < M; row++, col++)
    {
        for (i = row; i < N; i++)
            if (a[i][col]) break;
        if (i == N)
        {
            row--;
            continue;
        }
        if (i != row)
            for (j = 0; j <= M; j++) swap(a[row][j], a[i][j]);
        for (i = row + 1; i < N; i++)
        {
            if (a[i][col])
            {
                int LCM = lcm(a[row][col], a[i][col]);//利用最小公倍数去化上三角
                int ch1 = LCM / a[row][col], ch2 = LCM / a[i][col];
                for (j = col; j <= M; j++)
                    a[i][j] = ((a[i][j] * ch2 - a[row][j] * ch1)%MOD + MOD)%MOD;
            }

        }

    }

    for (i = row; i < N; i++)//无解
    {
        if (a[i][M] != 0)
        {
            printf("Inconsistent data.\n");
            return;
        }
    }
    if (row < M)//无穷多解
    {
        printf("Multiple solutions.\n");
        return;
    }
    //唯一解时
    for (i = M - 1; i >= 0; i--)
    {
        int ch = 0;
        for (j = i + 1; j < M; j++)
        {
            ch = (ch + ans[j] * a[i][j] % MOD)%MOD;
        }
        int last = ((a[i][M] - ch)%MOD + MOD)%MOD;
        int x = 0, y = 0;
        int d = extend_gcd(a[i][i], MOD, x, y);
        x %= MOD;
        if (x < 0) x += MOD;
        ans[i] = last*x / d%MOD;
        if (ans[i] < 3) ans[i] += 7;
    }
    for (int i = 0; i < M; i++)
    {
        if (i == 0)
            printf("%d", ans[i]);
        else
            printf(" %d", ans[i]);

    }
    printf("\n");
}

int main()
{

    while (scanf("%d%d", &M, &N), N || M)
    {
        memset(a, 0sizeof(a));
        memset(ans, 0sizeof(ans));
        int K;

        for (int i = 0; i < N; i++)
        {
            scanf("%d%s%s", &K, str1, str2);
            int last = ((solved(str2) - solved(str1) + 1)%MOD + MOD)%MOD;

            for (int j = 0; j < K; j++)
            {
                int v;
                scanf("%d", &v);
                a[i][v - 1] = (a[i][v - 1] + 1)%MOD;
            }
            a[i][M] = last;
        }
        Guass();
    }
}


你可能感兴趣的:(poj)