高斯消元

import java.util.*;
import java.io.*;
import java.math.*;

class Fraction {
    BigInteger a = BigInteger.ZERO, b = BigInteger.ONE;
    Fraction() { }
    Fraction(BigInteger a, BigInteger b)
    {
        BigInteger d = a.gcd(b);
        a = a.divide(d); b = b.divide(d);
        if (b.compareTo(BigInteger.ZERO) < 0) {
            a = a.negate(); b = b.negate();
        }
        this.a = a; this.b = b;
    }
    @Override
    public String toString()
    {
        BigInteger d = a.gcd(b);
        a = a.divide(d);
        b = b.divide(d);
        if (b.compareTo(BigInteger.ONE) == 0)
            return a.toString();
        return a + "/" + b;
    }
    public Fraction add(Fraction p)
    {
        return new Fraction(a.multiply(p.b).add(b.multiply(p.a)), b.multiply(p.b));
    }
    public Fraction subtract(Fraction p)
    {
        return new Fraction(a.multiply(p.b).subtract(b.multiply(p.a)), b.multiply(p.b));
    }
    public Fraction muliply(Fraction p)
    {
        return new Fraction(a.multiply(p.a), b.multiply(p.b));
    }
    public Fraction divide(Fraction p)
    {
        return new Fraction(a.multiply(p.b), b.multiply(p.a));
    }
    public Fraction abs()
    {
        return new Fraction(a.abs(), b.abs());
    }
    public int compareTo(Fraction p)
    {
        return a.multiply(p.b).subtract(b.multiply(p.a)).signum();
    }
}

class Matrix {
    Fraction data[][];
    
}

public class Main {
    
    // Gaussian elimination
    public static Fraction[] gaussianElimination(Fraction A[][], int m) throws Exception
    {
        for (int i = 0; i < m; ++i)
        {
            // Find pivot in column i, starting in row i:
            int maxi = i;
            for (int k = i + 1; k < m; ++k)
                if (A[k][i].abs().compareTo(A[maxi][i].abs()) > 0)
                    maxi = k;
            if (A[maxi][i].a.compareTo(BigInteger.ZERO) == 0)
                throw new Exception("no solution");
            // swap rows i and maxi, but do not change the value of i
            // Now A[i,i] will contain the old value of A[maxi,i].
            if (i != maxi) {
                Fraction tmp[] = A[i];
                A[i] = A[maxi];
                A[maxi] = tmp;
            }
            // divide each entry in row i by A[i,i]
            // Now A[i,i] will have the value 1.
            for (int k = m; k >= i; --k)
                A[i][k] = A[i][k].divide(A[i][i]);
            // subtract A[u,j] * row i from row u
            // Now A[u,j] will be 0, since A[u,j] - A[i,j] * A[u,j] = A[u,j] - 1 * A[u,j] = 0.
            for (int u = i + 1; u < m; ++u)
                for (int k = m; k > i; --k)
                    A[u][k] = A[u][k].subtract(A[u][i].muliply(A[i][k]));
        }
        
        Fraction x[] = new Fraction[m];
        x[m - 1] = A[m - 1][m].divide(A[m - 1][m - 1]);
        for (int i = m - 2; i >= 0; --i)
        {
            x[i] = A[i][m];
            for (int k = i + 1; k < m; ++k)
                x[i] = x[i].subtract(x[k].muliply(A[i][k]));
            x[i] = x[i].divide(A[i][i]);
        }
        return x;
    }
    
    public static void main(String args[])
    {
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        Fraction a[][] = new Fraction[105][105];
        Fraction x[] = new Fraction[105];
        
        while (cin.hasNext())
        {
            int m = cin.nextInt();
            for (int i = 0; i < m; ++i)
                for (int j = 0; j <= m; ++j)
                {
                    BigInteger tmp = cin.nextBigInteger();
                    a[i][j] = new Fraction(tmp, BigInteger.ONE);
                }
            try {
                x = gaussianElimination(a, m);
                for (int i = 0; i < m; ++i)
                    System.out.println(x[i]);
                System.out.println();
            } catch (Exception e) {
                System.out.println("No solution.");
                System.out.println();
            }
            
        }
    }
}

你可能感兴趣的:(J#)