标签:
两道题目类似,自己写的挫一直不对,后来祭出了kuangbin模板(枚举变元求最小解),慢慢练吧。。。
贴出1753的代码 3185直接改改初始化就行了
1 #include <queue> 2 #include <set> 3 #include <map> 4 #include <cstring> 5 #include <cmath> 6 #include <cstdio> 7 #include <iostream> 8 9 using namespace std; 10 //对2取模的01方程组 11 const int MAXN = 300; 12 //有equ个方程,var个变元。增广矩阵行数为equ,列数为var+1,分别为0到var 13 int equ,var; 14 int a[MAXN][MAXN]; //增广矩阵 15 int x[MAXN]; //解集 16 int free_x[MAXN];//用来存储自由变元(多解枚举自由变元可以使用) 17 int free_num;//自由变元的个数 18 19 //返回值为-1表示无解,为0是唯一解,否则返回自由变元个数 20 int Gauss() 21 { 22 int max_r,col,k; 23 free_num = 0; 24 for(k = 0, col = 0 ; k < equ && col < var ; k++, col++) 25 { 26 max_r = k; 27 for(int i = k+1;i < equ;i++) 28 { 29 if(abs(a[i][col]) > abs(a[max_r][col])) 30 max_r = i; 31 } 32 if(a[max_r][col] == 0) 33 { 34 k--; 35 free_x[free_num++] = col;//这个是自由变元 36 continue; 37 } 38 if(max_r != k) 39 { 40 for(int j = col; j < var+1; j++) 41 swap(a[k][j],a[max_r][j]); 42 } 43 for(int i = k+1;i < equ;i++) 44 { 45 if(a[i][col] != 0) 46 { 47 for(int j = col;j < var+1;j++) 48 a[i][j] ^= a[k][j]; 49 } 50 } 51 } 52 for(int i = k;i < equ;i++) 53 if(a[i][col] != 0) 54 return -1;//无解 55 if(k < var) return var-k;//自由变元个数 56 //唯一解,回代 57 for(int i = var-1; i >= 0;i--) 58 { 59 x[i] = a[i][var]; 60 for(int j = i+1;j < var;j++) 61 x[i] ^= (a[i][j] && x[j]); 62 } 63 return 0; 64 } 65 int n; 66 67 const int INF = 0x3f3f3f3f; 68 int solve() 69 { 70 int t = Gauss(); 71 if(t == -1) 72 { 73 return INF; 74 } 75 else if(t == 0) 76 { 77 int ans = 0; 78 for(int i = 0;i < n*n;i++) 79 ans += x[i]; 80 return ans; 81 } 82 else 83 { 84 //枚举自由变元 85 int ans = INF; 86 int tot = (1<<t); 87 for(int i = 0;i < tot;i++) 88 { 89 int cnt = 0; 90 for(int j = 0;j < t;j++) 91 { 92 if(i&(1<<j)) 93 { 94 x[free_x[j]] = 1; 95 cnt++; 96 } 97 else x[free_x[j]] = 0; 98 } 99 for(int j = var-t-1;j >= 0;j--) 100 { 101 int idx; 102 for(idx = j;idx < var;idx++) 103 if(a[j][idx]) 104 break; 105 x[idx] = a[j][var]; 106 for(int l = idx+1;l < var;l++) 107 if(a[j][l]) 108 x[idx] ^= x[l]; 109 cnt += x[idx]; 110 } 111 ans = min(ans,cnt); 112 } 113 return ans; 114 } 115 } 116 117 void init(int n) 118 { 119 memset(a,0,sizeof(a)); 120 int x,xx,y,yy; 121 for(int i=0;i<n*n;i++){ 122 x = i/n; 123 y = i%n; 124 for(int j=0;j<n*n;j++){ 125 xx = j/n; 126 yy = j%n; 127 if(abs(x-xx)+abs(y-yy)<=1) a[i][j] = 1; 128 else a[i][j] = 0; 129 } 130 } 131 } 132 int main() 133 { 134 135 char s[50][50]; 136 int n; 137 n = 4; 138 equ = var = n*n; 139 for(int i=0;i<n;i++){ 140 scanf("%s",s[i]); 141 } 142 init(n); 143 for(int i=0;i<n*n;i++){ 144 if(s[i/n][i%n] != ‘b‘) a[i][n*n] = 1; 145 } 146 147 int k = 0,kk = 0; 148 int res1 = solve(); 149 150 init(n); 151 for(int i=0;i<n*n;i++){ 152 if(s[i/n][i%n] == ‘b‘) a[i][n*n] = 1; 153 } 154 int res2 = solve(); 155 if(res1 == INF && res2 == INF) printf("Impossible\n"); 156 else{ 157 printf("%d\n",min(res1,res2)); 158 } 159 160 161 return 0; 162 }
标签:
原文地址:http://www.cnblogs.com/lmlyzxiao/p/4947165.html