高斯消元模板

mod 2 方程写法:

int Gauss(int n, int m){
    int r = 0, c = 0;
    while(r < n && c < m){
        int id = r;
        for(int i = r + 1; i < n; i++)
            if(maze[i][c] > maze[id][c])
                id = i;
        if(id != r){
            for(int j = c; j <= m; j++)
                swap(maze[id][j], maze[r][j]);
        }
        if(maze[r][c] != 0){
            for(int i = r + 1; i < n; i++){
                if(maze[i][c] == 0) continue;
                for(int j = c; j <= m; j++)
                    maze[i][j] ^= maze[r][j];
            }
            r++;
        }else fx[num++] = c;
        c++;
    }
    //无解:
    for(int i = r; i < n ;i++)
        if(maze[i][c] !=0 ) return -1;
    
    //多解://枚举自由变元个数
    if(r < m){
        int S = B(m - r), cnt , ans = oo;
            for(int s = 0; s <= s; s++){
            int st = s;
            cnt = 0;
            for(int i = 0; i < c - r; i++){
                x[fx[i]] = st & 1;
                if(x[fx[i]]) cnt++;
                st >>= 1;
            }
            for(int i = r - 1; i >= 0; i--){
                int k = 0;
                while(maze[i][k] == 0) k++;
                x[k] = maze[i][m];
                for(int j = k + 1; j < m; j++)
                    x[k] ^= (maze[i][j] && x[j]);
                if(x[k]) cnt++;
            }
            cmin(ans, cnt);
        }
        return m - r;//返回自由变元的个数
    }
    
    //唯一解:
    for(int i = m - 1; i >= 0; i--){  
        x[i] = maze[i][m];  
        for(int j = i + 1;j < m; j++)
            x[i] ^= (maze[i][j] && x[j]);
    }
    return 0;
}


int 型写法:(同余方程)

int Gauss(int n, int m){
    int r = 0, c = 0;
    for(int i = 0; i <=m; i++){
        x[i] = 0;
        fx[i] = 1;
    }
    while(r < n && c < m){
        int id = r;
        for(int i = r + 1; i < n; i++)
            if(maze[i][c] > maze[id][c])
                id = i;
        if(id != r){
            for(int j = c; j <= m; j++)
                swap(maze[id][j], maze[r][j]);
        }
        if(maze[r][c] != 0){
            for(int i = r + 1; i < n; i++){
                if(maze[i][c] == 0) continue;
                int LCM = lcm(abs(maze[r][c], abs(maze[i][c])));
                int ta = LCM / abs(maze[r][c]);
                int tb = LCM / abs(maze[i][c]);
                if(maze[i][c] * maze[r][c] < 0) ta = - ta;
                for(int j = c; j <= m; j++)
                    maze[i][j] = (maze[i][j] * tb - maze[r][j] * ta) % 7 + 7) % 7;
            }
            r++;
        }
        c++;
    }
    //无解:
    for(int i = r; i < n ;i++)
        if(maze[i][c] !=0 ) return -1;
    
    //多解://枚举自由变元个数
    if(r < m){
        for(int i = r - 1; i >=0; i--){
            int fxn = 0, fxi;
            for(int j = 0; j < m; j++)
                if(maze[i][j] != 0 && fx[j]) fxn++, fxi = j;
            if(fxi > 1) continue;
            int t = maze[i][m];
            for(int j = 0; j < m; j++)
                if(maze[i][j] != 0 && j != fxi)
                    t = ((t - maze[i][j] * x[j]) % 7 + 7) % 7;
            x[fxi] = (t / maze[i][fix]) % 7;
            fx[fxi] = 0;
        }
        return m - r;//返回自由变元的个数
    }
    
    //唯一解:
    for(int i = m - 1; i >= 0; i--){  
        int t = maze[i][m];  
        for(int j = i + 1;j < m; j++)
            if(maze[i][j] != 0)
                t = ((t - maze[i][j] * x[j]) %7 + 7) % 7;
        while(t % maze[i][i] != 0) t += 7;
        x[i] = (t / maze[i][i]) % 7;
    }
    return 0;
}

double 型写法:

//化成对角线
void Gauss(int n, int m){
	int r, c, k;
	for (r = c = 0; r < n && c < m; r++, c++){
		for (k = r; k < n; k++)
		if (fabs(a[k][c]) > eps)
			break;
		if (r == n) continue;
		if (k != r){
			for (int j = 0; j <= m; j++)
				swap(a[k][j], a[r][j]);
		}
		for (int j = c + 1; j <= m; j++)a[r][j] /= a[r][c];
		a[r][c] = 1.0;
		for (int i = 0; i < n; i++){
			if (i == r || fabs(a[i][c]) < eps) continue;
			for (int j = c + 1; j <= m; j++)
				a[i][j] -= a[i][c] * a[r][j];
			a[i][c] = 0.0;
		}
	}
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值