状态压缩+枚举 POJ 3279 Fliptile
2015-08-02 13:24
381 查看
题目传送门
/* 题意:问最少翻转几次使得棋子都变白,输出翻转的位置 状态压缩+枚举:和之前UVA_11464差不多,枚举第一行,可以从上一行的状态知道当前是否必须翻转 */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 20; const int INF = 0x3f3f3f3f; int a[MAXN][MAXN]; int b[MAXN][MAXN]; int ans[MAXN][MAXN]; int dx[5] = {-1, 0, 0, 0, 1}; int dy[5] = {0, 1, 0, -1, 0}; int n, m; int get_col(int x, int y) { int ret = a[x][y]; for (int i=0; i<5; ++i) { int tx = x + dx[i], ty = y + dy[i]; if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue; ret += b[tx][ty]; } return ret & 1; } int check(int s) { memset (b, 0, sizeof (b)); for (int i=0; i<m; ++i) { if (s & (1 << i)) b[0][i] = 1; } for (int i=1; i<n; ++i) { for (int j=0; j<m; ++j) { if (get_col (i-1, j)) b[i][j] = 1; } } for (int i=0; i<m; ++i) if (get_col (n-1, i)) return INF; int ret = 0; for (int i=0; i<n; ++i) { for (int j=0; j<m; ++j) ret += b[i][j]; } return ret; } int main(void) { //POJ 3279 Fliptile while (scanf ("%d%d", &n, &m) == 2) { for (int i=0; i<n; ++i) { for (int j=0; j<m; ++j) { scanf ("%d", &a[i][j]); } } int mn = INF; memset (ans, 0, sizeof (ans)); for (int i=0; i<(1<<m); ++i) { int res = check (i); if (res < mn) { mn = res; for (int i=0; i<n; ++i) { for (int j=0; j<m; ++j) { if (b[i][j]) ans[i][j] = 1; else ans[i][j] = 0; } } } } if (mn < INF) { for (int i=0; i<n; ++i) { for (int j=0; j<m; ++j) printf ("%d%c", ans[i][j], (j == m-1) ? '\n' : ' '); } } else puts ("IMPOSSIBLE"); } return 0; }
相关文章推荐
- Valid Parentheses
- unix标准出错输出文件stderr
- 四位计算机的原理及其实现
- 点击按钮改变textField的状态
- jq-准备篇
- Invert Binary Tree
- 教你轻松自定义ViewPagerIndicator
- linux shell(一)
- JavaScript基础-Function类
- 设计模式(代理模式--动态代理)
- 【练习笔记】剑指offer-输出n位数全排列
- 欢迎使用CSDN-markdown编辑器
- JDBC编程六步走
- 实习第一周总结
- 判断复选框是否被选择的方法
- Linux下SVN命令使用实例
- 好消息: 《微信商城开发实战》 已经由电子工业出版社出版发行啦
- Android TextView属性详解
- 读书笔记--TCP连接建立与终止
- leetcode之路022 Generate Parentheses