poj_1753_高斯消元
2015-07-21 20:29
351 查看
开心,总算过了,对于高斯消元的理解更深一步,这道题的重点在于,如果用高斯消元的话,最后一行是要枚举的,总共16种情况,因为不知道怎么枚举,当时卡了好久,其实在线性方程组中,我们可以当做缺少了四个方程,所以我们的过程就是枚举最后四个方程,然后一步一步往回带入。
其中要注意一点,就是最后的结果可以全是白面,也可以全是黑面,看了很多博客,说的解法都很麻烦,其实大可以不必,只要a数组加两列就行,将枚举的结果回带的时候,要多开两个数组记录下解空间,仅此而已。
其中要注意一点,就是最后的结果可以全是白面,也可以全是黑面,看了很多博客,说的解法都很麻烦,其实大可以不必,只要a数组加两列就行,将枚举的结果回带的时候,要多开两个数组记录下解空间,仅此而已。
[code]/*######################################################################### # File Name: poj_1753.cpp # Author: CaoLei # Created Time: 2015/7/21 14:02:56 #########################################################################*/ #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <set> #include <queue> #include <map> using namespace std; #define MAX(x,y) (((x)>(y))?(x):(y)) #define MIN(x,y) (((x)<(y))?(x):(y)) #define N 500010 #define pi acos(-1.0) #define inf 100000000 typedef long long ll; typedef unsigned long long ull; char str[10]; int a[20][20]; int x1[20]; int x2[20]; int gauss(){ //高斯消元基本过程 int i = 0, line = 0; for (;i<16;){ int p = line; for (int j = line + 1; j<16; j++) if (a[line][i]<a[j][i]) p = j; if (p != line) for (int j = 0; j <= 17; j++) swap(a[line][j], a[p][j]); if (a[line][i] == 0){ i++; continue; } for (int j = 0; j<16; j++){ if (j != line&&a[j][i]){ for (int k = i; k <= 17; k++) a[j][k] ^= a[line][k]; } } i++; line++; } bool f1 = true, f2 = true; for (int k = line; k<16; k++){ if (a[k][16]) f1 = false; if (a[k][17]) f2 = false; } if (!f1&&!f2) return -1; if(line==16) return 1; int ans=16; //这里记录下自由元的个数 int t=16-line; //枚举16种解的情况 for(int i=0;i<(1<<t);i++){ for(int j=0;j<16;j++){ x1[j]=a[j][16]; x2[j]=a[j][17]; } for(int j=0;j<t;j++){ if(i&(1<<j)){ x1[15-j]=1; x2[15-j]=1; } else { x1[15-j]=0; x2[15-j]=0; } } //回带的过程 for(int j=16-t-1;j>=0;j--){ int tmp1=0,tmp2=0; for(int k=j+1;k<16;k++){ if(a[j][k]) { tmp1^=x1[k]; tmp2^=x2[k]; } } //维护解空间 x1[j]^=tmp1; x2[j]^=tmp2; } int c1=0,c2=0; for(int ii=0;ii<16;ii++){ if(x1[ii]) c1++; if(x2[ii]) c2++; } //更新最小值 ans=MIN(ans,MIN(c1,c2)); } return ans; } int main(){ //freopen("in.txt","r",stdin); int nn=20; memset(a,0,sizeof(a)); for (int i = 0; i<4; i++){ scanf("%s", str); for (int j = 0; j<4; j++){ int tmp = i * 4 + j; if (str[j] == 'b') { a[tmp][16] = 0; a[tmp][17] = 1; } else{ a[tmp][16] = 1; a[tmp][17] = 0; } a[tmp][tmp] = 1; if (tmp>3) a[tmp - 4][tmp] = 1; if (tmp<12) a[tmp + 4][tmp] = 1; if (tmp % 4 != 0) a[tmp - 1][tmp] = 1; if (tmp % 4 != 3) a[tmp + 1][tmp] = 1; } } int ans = gauss(); if (ans == -1) printf("Impossible\n"); else printf("%d\n", ans); return 0; }
相关文章推荐
- 人丑就要多读书(13)
- 第5章面试2--专家打分
- scikit-learn:4.1. Pipeline and FeatureUnion: combining estimators(特征与预测器结合;特征与特征结合)
- C语言10 -- 动态内存分配
- st函数--区间最大最小值
- 算法之动态规划
- java中自动生成编码,例如18位,20位等
- JAVA从入门到精通书中ZIP压缩和解压缩错误修正
- 构造函数沉思录
- HDU 4548 美素数【树状数组+筛法求素数】
- C|C++中的静态全局变量,静态局部变量,全局变量,局部变量的区别
- Redis缓存
- 爱奇艺视频
- 关于java的基础--基本数据类型以及循环
- POJ 1019 Number Sequence 解读
- java JDBC 万能DAO的实现的补充 实现了增删查改
- Brackets Sequence 括号DP
- iOS开发-使用第三方库AFNetWorking解析JSON和XML数据
- 中介者模式 - 行为模式
- 结构体字节对齐