uva 684 - Integral Determinant(行列式求值)

题目连接:uva 684 - Integral Determinant

题目大意:给定一个行列式,求行列式的值。

解题思路:将行列式转化成上三角的形式,值即为对角线上元素的积。因为要消元,又是整数,所以用分数去写了。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long type;

struct Fraction {
    type member; // 分子;
    type denominator; // 分母;

    Fraction (type member = 0, type denominator = 1);
    void operator = (type x) { this->set(x, 1); }
    Fraction operator * (const Fraction& u);
    Fraction operator / (const Fraction& u);
    Fraction operator + (const Fraction& u);
    Fraction operator - (const Fraction& u);

    void set(type member, type denominator);
};

inline type gcd (type a, type b) {
    return b == 0 ? (a > 0 ? a : -a) : gcd(b, a % b);
}

inline type lcm (type a, type b) {
    return a / gcd(a, b) * b;
}

/*Code*/
/////////////////////////////////////////////////////
const int maxn = 105;
typedef long long ll;

int N;
Fraction A[maxn][maxn];;

/*
bool cmp (const Fraction& a, const Fraction& b) {
    ll p = a.member * b.denominator;
    ll q = a.denominator * b.member;

    if (p < 0)
        p = -p;
    if (q < 0)
        q = -q;
    return p > q;
}
*/

inline void self_swap (Fraction& a, Fraction& b) {
    Fraction tmp = a;
    a = b;
    b = tmp;
}

ll solve () {
    int sign = 1;
    Fraction ret = 1;

    for (int i = 0; i < N; i++) {
//        printf("%d!\n", i);
        int r = i;

        for (int j = i+1; j < N; j++)
            if (A[j][i].member)
                r = j;

        if (r != i) {
            for (int j = 0; j < N; j++)
                self_swap(A[i][j], A[r][j]);
            sign *= -1;
        }

        if (A[i][i].member == 0 || A[i][i].denominator == 0)
            return 0;

        for (int j = i + 1; j < N; j++) {
            Fraction f = A[j][i] / A[i][i];

            for (int k = N-1; k >= 0; k--) {
                A[j][k] = A[j][k] - (A[i][k] * f);
            }
        }
        ret = ret * A[i][i];
    }

    /*
       for (int i = 0; i < N; i++) {
       for (int j = 0; j < N; j++)
       printf("%lld/%lld ", A[i][j].member, A[i][j].denominator);
       printf("\n");
       }
       */
    if (ret.denominator < 0)
        sign *= -1;
    return ret.member * sign;
}

int main () {
    while (scanf("%d", &N) == 1 && N) {
        ll x;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                scanf("%lld", &x);
                A[i][j] = x;
            }
        }
        printf("%lld\n", solve());
    }
    printf("*\n");
    return 0;
}

/////////////////////////////////////////////////////

Fraction::Fraction (type member, type denominator) {
    this->set(member, denominator);
}

Fraction Fraction::operator * (const Fraction& u) {
    type tmp_p = gcd(member, u.denominator);
    type tmp_q = gcd(u.member, denominator);
    return Fraction( (member / tmp_p) * (u.member / tmp_q), (denominator / tmp_q) * (u.denominator / tmp_p) );
}

Fraction Fraction::operator / (const Fraction& u) {
    type tmp_p = gcd(member, u.member);
    type tmp_q = gcd(denominator, u.denominator);
    return Fraction( (member / tmp_p) * (u.denominator / tmp_q), (denominator / tmp_q) * (u.member / tmp_p));
}

Fraction Fraction::operator + (const Fraction& u) {
    type tmp_l = lcm (denominator, u.denominator);
    return Fraction(tmp_l / denominator * member + tmp_l / u.denominator * u.member, tmp_l);
}

Fraction Fraction::operator - (const Fraction& u) {
    type tmp_l = lcm (denominator, u.denominator);
    return Fraction(tmp_l / denominator * member - tmp_l / u.denominator * u.member, tmp_l);
}

void Fraction::set (type member, type denominator) {

    if (denominator == 0) {
        denominator = 1;
        member = 0;
    }

    type tmp_d = gcd(member, denominator);
    this->member = member / tmp_d;
    this->denominator = denominator / tmp_d;
}

uva 684 - Integral Determinant(行列式求值),布布扣,bubuko.com

时间: 2024-08-07 21:17:01

uva 684 - Integral Determinant(行列式求值)的相关文章

UVA 684 - Integral Determinant(行列式变换)

UVA 684 - Integral Determinant 题目链接 题意:给定一个行列式,求出值 思路:利用线性代数中的列相减,然后不断降阶即可,就是要用分数去写 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 35; long long gcd(long long a, long long b) { if (!b) re

Matrix Chain Multiplication UVA 442 (栈 表达式求值)

说说: 其实这道题是栈这个数据结构最经典的运用,即表达式的求值.与一般情况不同的是,此次要求的运算数是矩阵.在整个解析表达式的过程中,无非遇到三类字符,一个是'(',另一个是')',剩下的就是运算数了.首先,在遇到'('的时候,栈指针自动加一,并将栈顶元素的行数和列数都设置为-1,这样就不会和正常的运算数混淆了.如果遇到的是运算数,首先要判断当前的栈顶元素是否为运算数(当然,还要注意栈为空的特殊情况).若是,则直接将新的运算数与栈顶运算数进行计算,否则将新运算数入栈.还有最后一种情况就是遇到')

行列式求值 (取模)

typedef __int64 lld; lld a[205][205]; int sign; lld N,MOD; void solved() { lld ans=1; for(int i=0;i<N;i++)//当前行 { for(int j=i+1;j<N;j++)//当前之后的每一行,因为每一行的当前第一个数要转化成0(想想线性代数中行列式的计算) { int x=i,y=j; while(a[y][i])//利用gcd的方法,不停地进行辗转相除 { lld t=a[x][i]/a[y

行列式求值

var a:array[0..208,0..208] of int64; mo:int64; i,j,n,temp:longint; function guess:int64; var i,j,k,t:longint; ans:int64; begin ans:=1; for i:=1 to n do begin for j:=i+1 to n do begin while a[j,i]<>0 do begin t:=a[i,i] div a[j,i]; for k:=i to n do be

利用递归与行列式展开定理求行列式的值(数组指针版)

今天用数组指针改写了一下行列式求值程序,代码: 1 #include <iostream> 2 #include <cmath> 3 using namespace std; 4 int main() 5 { 6 int rank; 7 void setDet(double*,int); 8 double valDet(double*,int); 9 cout<<"输入行列式的阶数:"; 10 cin>>rank; 11 double *

求行列式的值(递归)

/* #include <math.h> #include <stdio.h> #define N 100 #define LIM -100000000 float det(float a[N][N],int n){ if(n==1) return a[0][0]; if(n==2) return a[0][0]*a[1][1]-a[0][1]*a[1][0];// the base situation else{ int j,i,flag=1; float ret=0; for(

老笔记整理五:C实现10阶内通过展开代数余子式求行列式的值

这个分为两部分,先是写出了C实现计算三阶行列式,然后过了一段时间突然有了思路才写下了10阶内这段代码.真怀念那段写代码的日子. 一:C实现计算三阶行列式 最近高数课在上线性代数,二阶的还能口算,三阶的有点麻烦,想陆陆续续地把公式都用C来实现.因为二阶的行列式如果用C来写就是一句话:val=det[0][0]*det[1][1]-det[0][1]*det[1][0];太简单了这里就不写了,主要写关于三阶的.只要把这个三阶行列式里每一个元素打进去就能算出值来了.过两天再写余子式的展开. 1 #in

C语言求行列式的值

#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <windows.h> #define NUM 3 int Fun(int n, int a[NUM][NUM]); /*函数声明*/ int main() { int i = 0, j = 0; /*i,j分别表示行与列*/ int a[3][3] = { {14,6,2},{6,3,3},{5,9,8} }; /

数据结构实验之栈三:后缀式求值

数据结构实验之栈三:后缀式求值 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 对于一个基于二元运算符的后缀表示式(基本操作数都是一位正整数),求其代表的算术表达式的值. 输入 输入一个算术表达式的后缀式字符串,以'#'作为结束标志. 输出 求该后缀式所对应的算术表达式的值,并输出之. 示例输入 59*684/-3*+# 示例输出 57 提示 基本操作数都是一位正整数! 来源 示例程序 #include <stdio.h>