2012-09-20 22:12:12Morris

[ZJ][一年後修裝版][C++] b113. 6. 線性系統求解

內容 :

輸入說明 :

輸出說明 :

本題因為結果為無限組任一輸出不太好確定是否為正確,

所以若結果為無限組的話,輸出N即可。 

測資改為多筆測資,

讀完第一個值n後,

後面的方程式請讀到EOF做結束。

(MAPLEWING 2011/01/19修正) 

範例輸入 :

[Input 1] <-純粹標明是第幾筆的測資,在測資的輸入裡面並沒有。3			2 8 4 22 5 1 54 10 -1 1[Input 2]31 2 3 08 10 12 67 8 9 6[Input 3]3			1 2 3 04 5 6 37 8 9 0[Input 4]13 10

範例輸出 :

[Output 1] <-純粹標明是第幾筆的測資,您不用輸出這個東西。1x1 = 11x2 = -4x3 = 3[Output 2]N[Output 3]0[Output 4]1x1 = 10/3

提示 :

出處 :

93全國資訊學科能力決賽



#include <cstdio>
#include <iostream>
using namespace std;
class Frac {
    public:
        long long a, b;
        Frac() {
            a = 0, b = 1;
        }
        Frac(int x, int y) {
            a = x, b = y;
            reduce();
        }
        Frac operator+(const Frac &y) {
            long long ta, tb;
            tb = this->b/gcd(this->b, y.b)*y.b;
            ta = this->a*(tb/this->b) + y.a*(tb/y.b);
            Frac z(ta, tb);
            return z;
        }
        Frac operator-(const Frac &y) {
            long long ta, tb;
            tb = this->b/gcd(this->b, y.b)*y.b;
            ta = this->a*(tb/this->b) - y.a*(tb/y.b);
            Frac z(ta, tb);
            return z;
        }
        Frac operator*(const Frac &y) {
            long long tx, ty, tz, tw, g;
            tx = this->a, ty = y.b;
            g = gcd(tx, ty), tx /= g, ty /= g;
            tz = this->b, tw = y.a;
            g = gcd(tz, tw), tz /= g, tw /= g;
            Frac z(tx*tw, ty*tz);
            return z;
        }
        Frac operator/(const Frac &y) {
            long long tx, ty, tz, tw, g;
            tx = this->a, ty = y.a;
            g = gcd(tx, ty), tx /= g, ty /= g;
            tz = this->b, tw = y.b;
            g = gcd(tz, tw), tz /= g, tw /= g;
            Frac z(tx*tw, ty*tz);
            return z;
        }
    private:
        static long long gcd(long long x, long long y) {
            if(!y)  return x;
            if(x < 0)   x *= -1;
            if(y < 0)   y *= -1;
            long long t;
            while(x%y)
                t = x, x = y, y = t%y;
            return y;
        }
        void reduce() {
            long long g = gcd(a, b);
            a /= g, b /= g;
            if(b < 0)   a *= -1, b *= -1;
        }
};
ostream& operator<<(ostream& out, const Frac&x) {
    out << x.a;
    if(x.b != 1)
        out << '/' << x.b;
    return out;
}
int main() {
    int n, m, i, j, k;
    scanf("%d", &n);
        m = n;
        Frac matrix[m][n+1];
        for(i = 0; i < m; i++) {
            for(j = 0; j <= n; j++) {
                scanf("%lld", &matrix[i][j].a);
            }
        }
        Frac tmp, one(1,1);
        int sol = 0;
        for(i = 0; i < m; i++) {
            int ch = i;
            for(j = i; j < m; j++)
                if(matrix[j][i].a) {
                    ch = j;
                    break;
                }
            if(i != ch)
                for(j = i; j <= n; j++)
                    tmp = matrix[i][j], matrix[i][j] = matrix[ch][j], matrix[ch][j] = tmp;
            if(matrix[i][i].a == 0) {
                sol = 1;continue;
            }
            tmp = one/matrix[i][i];
            for(j = i; j <= n; j++)
                matrix[i][j] = matrix[i][j]*tmp;
            for(j = 0; j < m; j++) {
                if(i == j)  continue;
                tmp = matrix[j][i]/matrix[i][i];
                for(k = i; k <= n; k++) {
                    matrix[j][k] = matrix[j][k] - tmp*matrix[i][k];
                }
            }
        }
        if(!sol) {
            puts("1");
            for(i = 0; i < m; i++) {
                printf("x%d = ", i+1);
                cout << matrix[i][m] << endl;
            }
        }
        for(i = 0; i < m; i++) {
            for(j = 0; j < m; j++) {
                if(matrix[i][j].a)
                    break;
            }
            if(j == m) {
                if(matrix[i][j].a == 0)
                    sol = 2;
                else
                    sol = 3;
                break;
            }
        }
        if(sol == 2)
            puts("N");
        else if(sol == 3)
            puts("0");
    return 0;
}

Morris 2012-09-21 07:33:31

Frac operator*(const Frac &y) {
若不加 const, 則只能一次操作, 無法進行 a = b+c*d;
兩個以上的運算操作, 跟區域變數的回傳有關, 那是一個屬於系統的物件, 是無法做更改的, 因此要確保不可被修改, 才加上 const 以進行四則運算。
by Inker 指導與心得所感