poj3279 Fliptile
来源:互联网 发布:ubuntu win7 系统时间 编辑:程序博客网 时间:2024/06/05 00:45
题意:给你一个n*m的黑白棋盘,问能否通过操作使得棋盘全变为白色。如果有求一种操作次数最少的方法(相同时要求字典序最小),没有输出"IMPOSSIBLE"。操作为:将某一块和它上下左右全部翻转。
思路:由于我们每次反转都会影响到上面的棋子,我们想全变为白色,我们需要从第二行到第n行每一行把它的上一行的黑色块翻转为白色,如果最后一行把上一行的翻转为白色之后最后一行还有黑色块,证明这种方法不能将棋盘全变白。我们可以发现只要第一行的状态一定,下面的翻法也就一定了。所以我们只需要枚举第一行的所有翻法就可以,我们可以通过用枚举二进制数字的方法来表示翻法。例如:n=5,m=5。00101表示第三块和最后一块进行翻转,此时二进制数最大为11111即(1<<5)-1。
//#include<bits/stdc++.h>#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int INF = 1e9 + 5;const int MAXN = 20;int n, m;bool MAP[MAXN][MAXN], ans[MAXN][MAXN];//地图和答案bool t[MAXN][MAXN], vis[MAXN][MAXN];//临时图和临时答案void FLIPS(int x, int y)//翻{ t[x][y] = !t[x][y];//自己 t[x - 1][y] = !t[x - 1][y];//上 t[x + 1][y] = !t[x + 1][y];//下 t[x][y - 1] = !t[x][y - 1];//左 t[x][y + 1] = !t[x][y + 1];//右}bool judge()//检查最后一行{ for(int i = 1; i <= m; i++) { if(t[n][i] == 1) return false;//有黑色的 } return true;}int work(int cnt)//2-n行翻转{ for(int i = 2; i <= n; i++) { for(int j = 1; j <= m; j++) { if(t[i - 1][j] == 1)//上一行的j位置为黑,那么就要翻转这一块 { vis[i][j] = true; FLIPS(i, j); cnt++; } } } if(judge()) return cnt;//最后一行全为白色 return INF;}int main(){ while(cin >> n >> m) { //输入 for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { cin >> MAP[i][j]; } } //求解 int MIN = INF;//存储步数最小值 for(int i = 0; i < (1 << m); i++)//枚举第一行踩的方法 { memcpy(t, MAP, sizeof(t));//MAP赋给一个临时图t memset(vis, 0, sizeof(vis));//vis表示踩哪 int cnt = 0;//统计这种方案下需要操作翻转的次数 for(int j = 0; j < m; j++)//对第一行进行操作 { if(i&(1 << j)) { vis[1][j + 1] = true; FLIPS(1, j + 1); cnt++; } } //work推出下面2-n行的翻转情况 if(work(cnt) < MIN)//更新步数和答案 { MIN = cnt; memcpy(ans, vis, sizeof(vis)); } } //cout << endl; if(MIN == INF)//没答案 { printf("IMPOSSIBLE\n");continue; } //输出答案 for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { cout << ans[i][j] << " "; } cout << endl; } }return 0;}/*4 41 0 0 10 1 1 00 1 1 01 0 0 1*/
阅读全文
0 0
- POJ3279 Fliptile
- POJ3279 Fliptile
- POJ3279-Fliptile
- poj3279 Fliptile
- poj3279 Fliptile
- POJ3279-Fliptile
- POJ3279-Fliptile
- POJ3279 Fliptile
- poj3279 Fliptile
- poj3279:Fliptile
- POJ3279-Fliptile
- poj3279 Fliptile
- POJ3279 Fliptile 【DFS】
- [搜索]poj3279 fliptile
- 【POJ3279】Fliptile(开关问题)
- POJ3279-Fliptile【反转问题】
- poj3279 Fliptile 好题
- POJ3279 Fliptile 【暴力】
- 特殊形式矩阵求逆
- C++的学习笔记(第四章:数组及自定义类型)
- 健壮性图
- Linux内核笔记 -- 锁
- 我从阿里面试回来,想和Java程序猿谈一谈
- poj3279 Fliptile
- Qt:引用外部库Plus
- 计算机与编程语言基础
- 2017-12-23php基础巩固学习第五天
- 数据结构实验之排序一:一趟快排
- VB阿拉伯数字金额转大写中文
- Java练习(7)——十进制转换为2、8、16进制(优化)
- 代码规范 : 抽象(ADT) 封装 与职责(1)
- [Flokirie的测试赛]Roy&October之取石子 【sg函数】