Uva 11464 Even Parity
2014-02-09 13:08
232 查看
给你一个n*n的矩阵,你的任务是把尽量少的0变成1,使得每个数字的上下左右元素之和是偶数。
直接暴力肯定会超时,找到行与行之间的关系,可以发现只要枚举第一行的所有情况,后面行都可以算出来。
直接暴力肯定会超时,找到行与行之间的关系,可以发现只要枚举第一行的所有情况,后面行都可以算出来。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 16; const int INF = 2100000000 / 2; int mat[maxn][maxn],ans,n; int getsum(int x,int y,int m[maxn][maxn]) { int ans = 0; if(x > 1) ans += m[x - 1][y]; if(x < n) ans += m[x + 1][y]; if(y > 1) ans += m[x][y - 1]; if(y < n) ans += m[x][y + 1]; return ans; } int check() { int matA[maxn][maxn],ret = 0; for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { matA[i][j] = mat[i][j]; } } for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { if(getsum(i,j,matA) & 1) { if(i == n || matA[i + 1][j] == 1) { return INF; } else { matA[i + 1][j] = 1; ret++; } } } } return ret; } void dfs(int pos,int ch) { if(pos > n) return; ans = min(check() + ch,ans); dfs(pos + 1,ch); if(mat[1][pos] == 0) { mat[1][pos] = 1; ans = min(ans,check() + ch + 1); dfs(pos + 1,ch + 1); mat[1][pos] = 0; } } int main() { int T; scanf("%d",&T); for(int kase = 1;kase <= T;kase++) { scanf("%d",&n); for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { scanf("%d",&mat[i][j]); } } ans = INF; dfs(1,0); printf("Case %d: ",kase); if(ans == INF) { puts("-1"); } else { printf("%d\n",ans); } } return 0; }
相关文章推荐
- UVa 11464 Even Parity
- [UVA11464]Even Parity(状压,枚举)
- UVA 11464 Even Parity(枚举)
- UVA 11464 Even Parity(暴力枚举)
- UVA - 11464 Even Parity
- UVA 11464 - Even Parity(枚举方法)
- UVA 11464 - Even Parity
- uva 11464 - Even Parity(暴力枚举)
- UVa_11464_Even Parity_机智地搜索
- uva 11464 Even Parity
- UVA 11464 Even Parity(递归枚举)
- Uva 11464 Even Parity
- UVA 11464 - Even Parity(枚举方法)
- UVA 11464 Even Parity (独特思路)
- uva - 11464 - Even Parity(部分枚举,递推)
- UVA 11464 Even Parity
- 【UVA】11464-Even Parity(二进制枚举子集)
- UVA 11464 Even Parity
- UVa 11464 Even Parity (想法题&部分枚举)
- uva11464 Even Parity