poj 3279(翻转问题贪心)
来源:互联网 发布:京东秒杀软件 编辑:程序博客网 时间:2024/06/05 18:31
翻转问题一般是从前面开始贪心,如果是一维的话直接从前面往后贪心,如果是二维的话,就得枚举第一行的状态,然后从第一行往下贪心。
这个题就是二维的开关问题,需要枚举第一行的状态,复杂度为2^n,然后往后遍历贪心。总复杂度为2^n * n*m,因为n < 15 && m < 15,所以能在时限内通过。
PS :要特判n == 1,把他当作一维的来做
Code:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn = 10 + 10;#define INF 0x3f3f3f3fint n,m;int a[maxn][maxn];int b[maxn][maxn];void work(int x,int y){ a[x][y] ^= 1; a[x - 1][y] ^= 1; a[x + 1][y] ^= 1; a[x][y - 1] ^= 1; a[x][y + 1] ^= 1;}int vis[maxn][maxn];int main(){ while( ~ scanf("%d%d",&n,&m)) { memset(vis,0,sizeof(vis)); for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) scanf("%d",&b[i][j]); if(n == 1 && m == 1) { if(b[1][1] == 1) puts("1"); else puts("0"); continue; } if(n == 1) { int ans = 0; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) a[i][j] = b[i][j]; for(int j = 1; j < m; j ++) { if(a[1][j] == 1) { work(1,j + 1); ans ++; vis[1][j + 1] = 1; } }// cout << ans << endl; bool flags = 1; for(int j = 1; j <= m; j ++) if(a[1][j] == 1) { flags = 0;// cout << j << endl; puts("IMPOSSIBLE"); break; } if(flags) for(int j = 1; j <= m; j ++) printf("%d%c",vis[1][j],j <= m - 1 ? ' ' : '\n'); continue; } int ans = INF; int temp; for(int k = 0; k < (1 << n); k ++)//枚举第一层的翻转顺序 { for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) a[i][j] = b[i][j]; int cnt = 0; memset(vis,0,sizeof(vis)); int temps = 0; for(int j = 1; j <= n; j ++) { if((1 << (j - 1)) & k) { work(1,j),vis[1][j] = 1,cnt ++; } } for(int i = 1; i < n; i ++) { for(int j = 1; j <= m; j ++) { if(a[i][j] == 1) { work(i + 1,j); cnt ++; vis[i + 1][j] = 1; } } } for(int j = 1; j <= m; j ++) if(a[n][j] == 1) { cnt = INF; break; }// cout << cnt << " "; if(cnt < ans) ans = cnt,temp = k; }// cout << endl; if(ans == INF) { puts("IMPOSSIBLE"); continue; } for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) a[i][j] = b[i][j]; memset(vis,0,sizeof(vis)); for(int j = 1; j <= n; j ++) { if((1 << (j - 1)) & temp) work(1,j),vis[1][j] = 1; } for(int i = 1; i < n; i ++) { for(int j = 1; j <= m; j ++) { if(a[i][j] == 1) { work(i + 1,j); vis[i + 1][j] = 1; } } } for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { printf("%d%c",vis[i][j],j < m ? ' ' : '\n'); } } } return 0;}
阅读全文
0 0
- poj 3279(翻转问题贪心)
- POJ-3279 经典翻转问题
- POJ 3279 Fliptile (翻转问题)
- poj 2709 贪心问题
- ***POJ 3279 Fliptile【格子翻转】
- POJ 1521-Entropy 贪心问题
- POJ 2709-Painters 贪心问题
- POJ-1700 过河问题【贪心】
- poj 3069 贪心+区间问题
- 贪心-POJ 1700 过河问题
- 矩阵翻转 贪心 水题
- [POJ 3276] Face The Right Way (翻转问题+技巧)
- POJ 1065-Wooden Sticks 贪心问题
- POJ 1065 木棍问题 贪心算法
- poj 1042 钓鱼问题 枚举+贪心
- poj 1083 hdu1050 Moving Tables 贪心问题
- poj 2573 Bridge (过桥问题 贪心)
- poj 1089 贪心之区间覆盖问题
- 差分约束系统
- android Rect类的使用
- (53)停止线程,interrupt()方法+标记修改
- 机器学习笔记之过拟合问题
- pytorch GAN生成对抗网络
- poj 3279(翻转问题贪心)
- 机器学习中几种损失函数的分析
- idea 配置远程tomcat断点调试
- Python中如何实现分层抽样
- Linux下java编译运行时引用第三方jar包的方法
- java 简易的万年历
- c#后台执行js的五种方法
- java——开发DOM对象操作
- 怎么只显示日期的年/月/日呢