Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 5329 | Accepted: 2081 |
Description
Input
Output
Sample Input
0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0
Sample Output
3
Hint
题意:
给你一排碗,当翻动其中一个时,它和周围两个都翻转,多变元枚举最小值
/* poj3185 给你20个碗排成一排,当翻动其中一个时,它和周围两个都翻转 */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; typedef long double ld; using namespace std; const int maxn = 40; int equ,var; int a[maxn][maxn]; int b[maxn][maxn]; int x[maxn]; int free_x[maxn]; int free_num; int Gauss() { int max_r,col,k; free_num = 0; for(k = 0,col = 0; k < equ && col < var; k++,col++) { max_r = k; for(int i = k+1; i < equ; i++) { if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i; } if(a[max_r][col] == 0) { k --; free_x[free_num++] = col; continue; } if(max_r != k) { for(int j = col; j < var+1; j++) swap(a[k][j],a[max_r][j]); } for(int i = k + 1; i < equ; i++) { if(a[i][col] != 0) { for(int j = col; j < var+1; j++) a[i][j] ^= a[k][j]; } } } for(int i = k; i < equ; i++) if(a[i][col] != 0) 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; } int n; void ini() { memset(a,0,sizeof(a)); memset(x,0,sizeof(x)); equ = 20; var = 20; for(int i = 0;i < 20;i++) { a[i][i] = 1; if(i > 0) a[i-1][i] = 1; if(i < 20-1) a[i+1][i]= 1; } } int solve() { int t = Gauss(); if(t == -1) { return t; } else if(t == 0) { int ans = 0; for(int i = 0; i < n*n; i++) ans += x[i]; return ans; } else { int ans = 0x3f3f3f3f; int tot = (1 << t); for(int i = 0; i < tot; i++) { int cnt = 0; for(int j = 0; j < t; j++) { if(i & (1 << j)) { cnt ++; x[free_x[j]]= 1; } else x[free_x[j]]= 0; } for(int j = var-t-1; j >= 0; j--) { int dex; for(dex = j; dex < var; dex++) if(a[j][dex]) break; x[dex] = a[j][var]; for(int l = dex +1; l <var ; l++) { if(a[j][l]) x[dex] ^= x[l]; } cnt += x[dex]; } ans = min(ans,cnt); } return ans; } } int main() { int tx; while(scanf("%d",&tx) != EOF) { ini(); if(tx == 1) a[0][20] = 1; else a[0][20] = 0; for(int i= 1; i < 20; i ++) { scanf("%d",&tx); if(tx == 1) a[i][20] = 1; else a[i][20] = 0; } int t = solve(); printf("%d\n",t); } return 0; }