poj 1631 Painter's Problem(数学:高斯消元)

来源:互联网 发布:iphone社交软件 编辑:程序博客网 时间:2024/05/16 07:43

建立方程的过程和poj 1222基本相同

这道题求的是如果能把所有墙都变为黄色所需要的最少操作次数

这里看不明白是怎么做的

在网上找了很多代码。。。但是都没有注释

算了,这个题的意义就在于熟悉建立方程以及解方程的过程

代码如下:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAXN 400using namespace std;int equ, var;int x[MAXN];int free_x[MAXN];int a[MAXN][MAXN];char chs[MAXN*MAXN];char str[MAXN][MAXN];void print(int n) {    for(int i=0; i<n; ++i) {        for(int j=0; j<=n; ++j) {            printf("%d ", a[i][j]);        }        puts("");    }}int gauss() {    int i, j, k, max_r;    int col = 0;    for(k=0, col=0; k<equ&&col<var; ++k, ++col) {        max_r = k;        for(i=k+1; i<equ; ++i) {            if(a[i][col] > a[max_r][col])                max_r = i;        }        if(max_r != k) {            for(j=0; j<=var; ++j)                swap(a[k][j], a[max_r][j]);        }        if(a[k][col] == 0) {            --k;            continue;        }        for(i=k+1; i<equ; ++i) {            if(a[i][col])                for(j=col; j<=var; ++j)                    a[i][j] ^= a[k][j];        }    }    for(int i=k; i<equ; ++i) {        if(a[i][col])            return -1;    }    if(k < var) return var-k;    for(int i=var-1; i>=0; --i) {        x[i] = a[i][var];        for(int j=i+1; j<var; ++j)            x[i] ^= (a[i][j]&&x[j]);    }    return 0;}void solve() {    int ans = gauss();    if(ans == -1) {//无解        puts("inf");        return ;    } else if(ans == 0) {//唯一解        int res = 0;        for(int i=0; i<equ; ++i)            res += x[i];        printf("%d\n", res);        return ;    } else {//多解,这里看不懂。。。        int res = 0x3f3f3f3f;        int tot = (1<<ans);        for(int i=0; i<tot; ++i) {            int cnt = 0;            for(int j=0; j<ans; ++j) {                if(i&(1<<j)) {                    x[free_x[j]] = 1;                    ++cnt;                } else x[free_x[j]] = 0;            }            for(int j=var-ans-1; j>=0; --j) {                int idx;                for(idx=j; idx<var; ++idx)                    if(a[j][idx])                        break;                x[idx] = a[j][var];                for(int l=idx+1; l<var; ++l)                    if(a[j][l])                        x[idx] ^= x[l];                cnt += x[idx];            }            res = min(res, cnt);        }        printf("%d\n", res);    }}int main(void) {    int T, n;    scanf("%d", &T);    while(T--) {        scanf("%d", &n);        equ = var = n*n;        memset(a, 0, sizeof(a));        memset(x, 0, sizeof(x));        memset(free_x, 0, sizeof(free_x));        for(int i=0; i<n; ++i)            scanf("%s", str[i]);        int cnt = 0;        for(int i=0; i<n; ++i)            for(int j=0; j<n; ++j)            chs[cnt++] = str[i][j];        for(int i=0; i<cnt; ++i) {            a[i][i] = 1;            if(i%n != 0) a[i][i-1] = 1;            if(i%n != n-1) a[i][i+1] = 1;            if(i >= n) a[i][i-n] = 1;            if(i < n*n-n) a[i][i+n] = 1;        }        for(int i=0; i<cnt; ++i) {            a[i][n*n] = (chs[i]=='y' ? 0 : 1);        }        //print(n*n);        //solve();        gauss(n*n);    }    return 0;}


0 0
原创粉丝点击