高斯消元——求矩阵的秩

题目大意

如题,给你一个n行m列的矩阵,求它的秩。

样例输入

3 5
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15

3 3
2 0 2
0 2 0
2 0 2

样例输出

1
2

代码如下

#include
#include
#include
#include
#include
#include
#include
#include
#define CLR(x) memset(x,0,sizeof(x))
#define LL long long
using namespace std;

double mat[300][300];
int r,c;

void debug(){
    printf(" \n debug : \n");
    for(int i = 1 ; i <= r ; i++){
        for(int j = 1 ; j <= c ;j++){
            printf("%.0lf  ",mat[i][j]);
        }
        printf("\n");
    }
}
                                                      //保证一定得精度。
int cmp(double x,double y){
    double v = x - y;
    if(v > 1e-1) return 1;
    if(v < -1e-1) return -1;
    return 0;
}

void subrow(int r1 , int r2,double temp){
    for(int i = 1 ; i <= c ; i++){
        mat[r1][i] -= mat[r2][i]*temp;
    }
}

void swaprow(int r1 , int r2){
    for(int i = 1 ; i <= c ; i++){
        swap(mat[r1][i],mat[r2][i]);
    }
}

void solve(){
    for(int i = 1 ; i <= r ; i++){
        //debug();
        for(int cal = i ; cal <= c ; cal++){            //对这 i 行的每一列来找,要是这列本身和之下的列全是0,则找 i 行下一列。
            bool flag = true;
            
            if(cmp(mat[i][cal],0) == 0)
            {
                flag = false;                          //如果第 i 行 cal 列这个位置是 0 ,那找找这列下面的行有没有
                for(int j = i+1 ; j <= r ; j++){       //一个不为 0 的数 , 要是有 , 就将它与 i 行交换。
                    int tmp = cmp(mat[j][cal],0);
                    if(tmp == 1 || tmp == -1){
                        flag = true;
                        swaprow(j,i);
                        break;
                    }
                }
            }
            
            
            if(!flag) continue;                        //如果这列全是 0 , 到下一列。
            
            
            int v = i ;                                 //如果发现这列有值不为 0 并把它跟 i 行交换后,
            int maxn = mat[i][cal];                     //就再找这列有没有比 i 行 这个位置的值更大的值,如果有,将那一行
            for(int j = i+1 ; j <= r ; j++){            //跟i行交换。(听说是为了减小误差)
                if(cmp(mat[j][cal],mat[i][cal]) == 1){
                    v = j; maxn = mat[j][cal];
                }
            }
            if(v!=i){
                swaprow(i,v);
                //debug();
            }
            
                                                        //相减。(全程确保精度)
            for(int j = 1 ; j <= r ; j++){
                if(j == i) continue;
                if(cmp(mat[i][cal],0) == 0) continue;
                double tmp = mat[j][cal] / mat[i][cal];
                subrow(j,i,tmp);
            }
            break;
        }
    }
}

int main()
{
    CLR(mat);
    scanf("%d%d",&r,&c);
    for(int i = 1 ; i <= r ; i++){
        for(int j = 1 ; j <= c ; j++){
            scanf("%lf",&mat[i][j]);
        }
    }
    solve();
    //debug();

    bool f = false;
    int ans = 0;
    for(int i = r ; i >= 1 ; i--){
        for(int j = 1 ; j <= c ; j++){
            int tmp = cmp(mat[i][j],0);
            if(tmp == 1 || tmp == -1){
                f = true;break;
            }
        }
        if(f){
            ans = i;break;
        }
    }

    printf("%d\n",ans);
}

你可能感兴趣的:(高斯消元——求矩阵的秩)