算法与竞赛(第15章) - 矩阵高级运算

第1关:矩阵(方阵)行列式

//
//  main.cpp
//  step1
//
//  Created by ljpc on 2018/11/29.
//  Copyright © 2018年 ljpc. All rights reserved.
//

#include <iostream>
#include <algorithm>

using namespace std;

int det(int n, int** mat)
{
    int mov = 0;
    int flag;
    int sum = 0;
    if (n == 1) return mat[0][0];
    int** b = new int* [n - 1];
    for (int z = 0; z < n - 1; ++z)
        b[z] = new int[n - 1];
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n - 1; ++j) {
            mov = i > j ? 0 : 1;
            for (int k = 0; k < n - 1; ++k)
                b[j][k] = mat[j + mov][k + 1];
        }
        if (i % 2 == 0) flag = 1;
        else flag = -1;
        sum += flag * mat[i][0] * det(n - 1, b);
    }
    delete[] b;
    return sum;
}

struct Matrix {
    int m, n;
    int** val;
    Matrix() {}
    Matrix(int m_, int n_) {
        m = m_;
        n = n_;
        this->val = (int**)malloc(sizeof(int*) * m);
        for (int i = 0; i < m; i++) {
            this->val[i] = (int*)malloc(sizeof(int) * n);
        }
    }
    void in() {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                scanf("%d", &this->val[i][j]);
            }
        }
    }
    void out() {
        for (int i = 0; i < m; i++) {
            printf("%d", this->val[i][0]);
            for (int j = 1; j < n; j++) {
                printf(" %d", this->val[i][j]);
            }
            printf("\n");
        }
    }
    int Determinant_1() {
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        return val[0][0];
        /********* End *********/
    }
    int Determinant_2() {
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        return (val[0][0] * val[1][1] - val[0][1] * val[1][0]);
        /********* End *********/
    }
    int Determinant_3() {
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        int left = val[0][0] * val[1][1] * val[2][2] + val[0][1] * val[1][2] * val[2][0] + val[1][0] * val[2][1] * val[0][2];
        int right = val[2][0] * val[1][1] * val[0][2] + val[1][0] * val[0][1] * val[2][2] + val[2][1] * val[1][2] * val[0][0];
        return left - right;
        /********* End *********/
    }
    int Inverse_Number(int n, int arr[]) {
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        int count = 0;
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                if (arr[i] > arr[j]) {
                    count++;
                    break;
                }
            }
        }
        return count;
        /********* End *********/
    }
    int Determinant_n() {
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        int res = det(this->n, this->val);
        return res;
        /********* End *********/
    }

    int Determinant() {
        if (this->n == 1) {
            return Determinant_1();
        }
        else if (this->n == 2) {
            return Determinant_2();
        }
        else if (this->n == 3) {
            return Determinant_3();
        }
        else {
            return Determinant_n();
        }
    }

};

int main(int argc, const char* argv[]) {

    int n;
    scanf("%d", &n);
    Matrix A(n, n);
    A.in();

    int det = A.Determinant();
    printf("Det(A)=%d\n", det);

    return 0;
}


第2关:矩阵逆运算

//
//  main.cpp
//  step2
//
//  Created by ljpc on 2018/11/29.
//  Copyright © 2018年 ljpc. All rights reserved.
//

#include <iostream>
#include <algorithm>

using namespace std;

#define eps 1e-8
inline int sig(double x){return (x>eps)-(x<-eps); }

struct Matrix{
    int m, n;
    double **val;
    Matrix(){}
    Matrix(int m_, int n_){
        m = m_;
        n = n_;
        this->val = (double**)malloc(sizeof(double*)*m);
        for(int i=0;i<m;i++){
            this->val[i] = (double*)malloc(sizeof(double)*n);
        }
    }
    void in(){
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                scanf("%lf", &this->val[i][j]);
            }
        }
    }
    void out(){
        for(int i=0;i<m;i++){
            printf("%.4lf", this->val[i][0]);
            for(int j=1;j<n;j++){
                printf(" %.4lf", this->val[i][j]);
            }
            printf("\n");
        }
    }
    Matrix operator * (const double r)const{
        int m_ = this->m;
        int n_ = this->n;
        Matrix A = *this;
        Matrix M(m_, n_);
        for(int i=0;i<m_;i++){
            for(int j=0;j<n_;j++){
                M.val[i][j] = A.val[i][j] * r;
            }
        }
        return M;
    }
    Matrix operator * (const Matrix B)const{
        Matrix A = *this;
        Matrix M(A.m, B.n);
        if(A.n!=B.m){
            printf("error\n");
        }
        for(int i=0;i<A.m;i++){
            for(int j=0;j<B.n;j++){
                double sum = 0;
                for(int k=0;k<A.n;k++){
                    sum += A.val[i][k] * B.val[k][j];
                }
                M.val[i][j] = sum;
            }
        }
        return M;
    }
    int Inverse_Number (int n, int arr[]) {
        int num = 0;
        for(int i=0;i<n;i++){
            for(int j=0;j<i;j++){
                if(arr[j]>arr[i]){
                    num++;
                }
            }
        }
        return num;
    }
    double Determinant () {
        Matrix D = *this;
        double det = 0;
        int *arr;
        arr = (int*)malloc(sizeof(int)*D.n);
        for(int i=0;i<D.n;i++){
            arr[i] = i;
        }
        do{
            int inv = Inverse_Number(D.n, arr);
            double tmp = (inv%2==0)?1:-1;
            for(int i=0;i<D.n;i++){
                tmp *= D.val[i][arr[i]];
            }
            det += tmp;
        }while(next_permutation(arr, arr+D.n));
        return det;
    }
    
    
    double Cofactor (int x, int y) {
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        Matrix C = Matrix(this->n-1,this->n-1);
        for(int i=0;i<x;i++){
            for(int j=0;j<y;j++){
                C.val[i][j] = this->val[i][j];
            }
        }
        for(int i=0;i<x;i++){
            for(int j=y+1;j<this->n;j++){
                C.val[i][j-1] = this->val[i][j];
            }
        }
        for(int i=x+1;i<this->n;i++){
            for(int j=0;j<y;j++){
                C.val[i-1][j] = this->val[i][j];
            }
        }
        for(int i=x+1;i<this->n;i++){
            for(int j=y+1;j<this->n;j++){
                C.val[i-1][j-1] = this->val[i][j];
            }
        }
        double det_c = C.Determinant();
        return det_c;
        /********* End *********/
    }
    
    Matrix Adjugate_Matrix () {
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        Matrix A = Matrix(this->n, this->n);
        for(int i=0;i<A.n;i++){
            for(int j=0;j<A.n;j++){
                int flag = ((i+j)%2==0)?1:-1;
                int M_ij = Cofactor(i, j);
                A.val[j][i] = flag * M_ij;
            }
        }
        return A;
        /********* End *********/
    }
    
    Matrix Inverse_Matrix (){
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        double det = Determinant();
        if(det == 0){
            printf("error\n");
            return Matrix();
        }
        Matrix I = Matrix(this->n, this->n);
        Matrix A = Matrix(this->n, this->n);
        A = Adjugate_Matrix();
        I = A * (1./det);
        return I;
        /********* End *********/
    }
    
    bool Identity_Matrix() {
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        for(int i=0;i<this->n;i++){
            for(int j=0;j<this->n;j++){
                if(i==j){
                    if(sig(this->val[i][j]-1)!=0){
                        return false;
                    }
                }else {
                    if(sig(this->val[i][j]-0)!=0){
                        return false;
                    }
                }
            }
        }
        return true;
        /********* End *********/
    }
    
};

int main(int argc, const char * argv[]) {
    
    int n;
    scanf("%d", &n);
    Matrix A(n,n);
    A.in();
    
    Matrix I(n,n);
    I = A.Inverse_Matrix();
    I.out();
    
    Matrix E1(n,n);
    Matrix E2(n,n);
    E1 = A*I;
    E2 = I*A;
    if(E1.Identity_Matrix()==false){
        printf("A*I error\n");
        E1.out();
    }
    if(E2.Identity_Matrix()==false){
        printf("I*A error\n");
        E2.out();
    }
    
    return 0;
}


 第3关:矩阵初等变换

 

//
//  main.cpp
//  step3
//
//  Created by ljpc on 2018/11/29.
//  Copyright © 2018年 ljpc. All rights reserved.
//

#include <iostream>
#include <algorithm>

using namespace std;

#define eps 1e-8
inline int sig(double x){return (x>eps)-(x<-eps); }

struct Matrix{
    int m, n;
    double **val;
    Matrix(){}
    Matrix(int m_, int n_){
        m = m_;
        n = n_;
        this->val = (double**)malloc(sizeof(double*)*m);
        for(int i=0;i<m;i++){
            this->val[i] = (double*)malloc(sizeof(double)*n);
        }
    }
    void in(){
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                scanf("%lf", &this->val[i][j]);
            }
        }
    }
    void out(){
        for(int i=0;i<m;i++){
            printf("%.4lf", this->val[i][0]+eps);
            for(int j=1;j<n;j++){
                printf(" %.4lf", this->val[i][j]+eps);
            }
            printf("\n");
        }
    }
    
    Matrix Elementary_Row_Transformation (){
        
        Matrix R = Matrix(this->n, this->n*2);
        for(int i=0;i<this->n;i++){
            for(int j=0;j<this->n;j++)
                R.val[i][j] = this->val[i][j];
            for(int j=this->n;j<this->n*2;j++)
                R.val[i][j] = ((j-this->n)==i)?1:0;
        }
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
        for(int i=0;i<R.m;i++){
            double flag = R.val[i][i];
            for(int j=i;j<R.n;j++){
                R.val[i][j] /= flag;
            }
            for(int k=i+1;k<R.m;k++){
                flag = R.val[k][i];
                for(int j=i;j<R.n;j++){
                    R.val[k][j] -= flag * R.val[i][j];
                }
            }
        }
       
        for(int i=R.m-1;i>=0;i--){
            double flag = R.val[i][i];
            for(int j=i;j<R.n;j++){
                R.val[i][j] /= flag;
            }
            for(int k=i-1;k>=0;k--){
                flag = R.val[k][i];
                for(int j=k;j<R.n;j++){
                    R.val[k][j] -= flag * R.val[i][j];
                }
            }
        }

        /********* End *********/
        
        return R;
    }
    
    Matrix Elementary_Col_Transformation (){
        
        Matrix C = Matrix(this->n*2, this->n);
        for(int j=0;j<this->n;j++){
            for(int i=0;i<this->n;i++)
                C.val[i][j] = this->val[i][j];
            for(int i=this->n;i<this->n*2;i++)
                C.val[i][j] = ((i-this->n)==j)?1:0;
        }
        // 请在这里补充代码,完成本关任务
        /********* Begin *********/
          for(int j=0;j<C.n;j++){
            double flag = C.val[j][j];
            for(int i=j;i<C.m;i++){
                C.val[i][j] /= flag;
            }
            for(int k=j+1;k<C.n;k++){
                flag = C.val[j][k];
                for(int i=j;i<C.m;i++){
                    C.val[i][k] -= flag * C.val[i][j];
                }
            }
        }
        
        for(int j=C.n-1;j>=0;j--){
            double flag = C.val[j][j];
            for(int i=j;i<C.m;i++){
                C.val[i][j] /= flag;
            }
            for(int k=j-1;k>=0;k--){
                double flag = C.val[j][k];
                for(int i=j;i<C.m;i++){
                    C.val[i][k] -= flag * C.val[i][j];
                }
            }
        }

        /********* End *********/
        
        return C;
    }
};

int main(int argc, const char * argv[]) {

    int n;
    scanf("%d", &n);
    Matrix A(n,n);
    A.in();
    
    Matrix R = Matrix(n, n*2);
    R = A.Elementary_Row_Transformation();
    R.out();
    printf("\n");
    
    Matrix C = Matrix(n*2, n);
    C = A.Elementary_Col_Transformation();
    C.out();
    printf("\n");
    
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值