poj 3185 The Water Bowls 高斯消元

来源:互联网 发布:手绘pop软件 编辑:程序博客网 时间:2024/05/21 06:40

经典开关问题,不过这回给出的是一行开关而不是矩阵开关。高斯消元枚举自由变元

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int n = 20;int a[22][22] , x[22], freex[22],xx[22];void debug(){puts("debug");int i,j;for(i = 0;i < n; i++){for(j = 0;j < n+1;j ++)printf("%d ",a[i][j]);puts("");}puts("end");}void gauss(){int i,j,l;int row = 0, col = 0;//debug();for(; row < n && col < n; row++, col++){int maxr = row;for(i = row+1;i < n; i++)if(a[i][col])maxr = i;if(!a[maxr][col]){row --;continue;}if(row != maxr)for(i = col;i < n+1;i ++)swap(a[maxr][i] , a[row][i]);for(i = row+1;i < n ;i++)if(a[i][col])for(j = col;j < n+1; j++)a[i][j] ^= a[row][j];}//debug();int ans = 0;for(i = n-1;i >= 0; i--){x[i] = a[i][n];for(j = i+1;j < n; j++)if(x[j] && a[i][j])x[i] ^= 1;if(x[i])ans ++;}for(i = 0;i < n; i++)freex[i] = 1;for(i = row-1;i >= 0; i--){int num = 0 , id;for(j = i;j < n; j++)if(a[i][j] && freex[j])num ++ , id = j;if(num > 1)continue;x[id] = a[i][n];for(j = id+1;j < n; j++)if(a[i][j])x[id] ^= 1;freex[id] = 0;}int num = 0;int k = n-row;int N = 1<<k;for(i = n-1;i >= 0 && num < k;i--)if(freex[i])xx[num++] = i;for(j = i;j >= 0; j--)freex[i] = 0;for(i = 0;i < N; i++){int sum = 0;for(j = 0;j < k; j++)if(i & (1<<j))x[xx[j]] = 1,sum++;elsex[xx[j]] = 0;for(j = row-1;j >= 0;j --){for(l = j;l < n; l++)if(a[j][l])break;int id = l;x[id] = a[j][n];for(l = id+1;l < n; l++)if(a[j][l] && x[l])x[id] ^= 1;if(x[id])sum++;}if(sum < ans)ans = sum;}printf("%d\n", ans);}int main(){int i;memset(a,0,sizeof(a));for(i = 0;i < n; i++)scanf("%d", &a[i][20]);for(i = 0;i < n ;i++){a[i][i] = 1;if(i > 0)a[i][i-1] = 1;if(i < n-1)a[i][i+1] = 1;}gauss();return 0;}