题目大意 如题,给你一个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); }