POJ 3279 - Fliptile - [状压+暴力枚举]
题目链接:http://poj.org/problem?id=3279
Sample Input
4 4
1 0 0 1
0 1 1 0
0 1 1 0
1 0 0 1
Sample Output
0 0 0 0
1 0 0 1
1 0 0 1
0 0 0 0
题意:
给出 $M$ 行 $N$ 的矩阵,每个元素只为 $0$ 或者 $1$,分别代表白块和黑块,
每次可以翻转一个元素,使得它可以从黑变白或者从白变黑,但是上下左右相邻的四个元素也会跟着翻转,
求最少翻转多少个元素,可以使得全部元素均变成 $0$。
给出需要反转的元素,若有多个答案,给出字典序最小的,若无答案,输出"IMPOSSIBLE"。
题解:
首先,显然的:翻转只有 $0$ 次和 $1$ 次,多了没用;其次,翻转顺序无关性,结果与翻转方块的顺序无关,只与翻转那几个方块有关。
如果从上往下一行一行看,那么当第 $i$ 行确定了如何翻转后,第 $i$ 行上如果剩下来若干个黑块,那么只能靠翻转第 $i+1$ 行来将其变成白块,
这就注定了:一旦确定了第 $1$ 行如何翻转,后面的所有行如何翻转都被确定。
所以只要枚举第 $1$ 行所有翻转方案即可,列数不超过15,可以使用状压。
另外,由于第一行的翻转方案一旦给定,后面三行就是固定的,所以翻转方案的字典序可以只看第一行,
所以方案可以存成一个结构体,在存储方案数组的同时,一并存储总的翻转次数,以及,第一行翻转方案(存成二进制数);在最后进行排序,并输出第一个即可。
AC代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std; const int maxn=; int m,n;
int mp[maxn][maxn],tmp[maxn][maxn]; struct Ans{
int idx;
int times;
int f[maxn][maxn];
Ans()
{
this->times=;
memset(f,,sizeof(f));
}
};
bool cmp(Ans a,Ans b)
{
if(a.times==b.times) return a.idx<b.idx;
return a.times<b.times;
} inline void flip(int i,int j)
{
if(i>) tmp[i-][j]^=;
if(i<m) tmp[i+][j]^=;
if(j>) tmp[i][j-]^=;
if(j<n) tmp[i][j+]^=;
tmp[i][j]^=;
} inline bool allwhite()
{
for(int i=;i<=m;i++) for(int j=;j<=n;j++) if(tmp[i][j]) return ;
return ;
} int main()
{
cin>>m>>n;
for(int i=;i<=m;i++) for(int j=;j<=n;j++) cin>>mp[i][j]; vector<Ans> v;
for(int sta=;sta<(<<n);sta++)
{
for(int i=;i<=m;i++) for(int j=;j<=n;j++) tmp[i][j]=mp[i][j]; Ans ans;
for(int j=;j<=n;j++) if(sta&(<<(n-j))) flip(,j), ans.f[][j]=, ans.times++;
for(int i=;i<=m;i++) for(int j=;j<=n;j++) if(tmp[i-][j]) flip(i,j), ans.f[i][j]=, ans.times++;
if(allwhite())
{
ans.idx=sta;
v.push_back(ans);
}
}
sort(v.begin(),v.end(),cmp);
if(v.size()>) for(int i=;i<=m;i++) for(int j=;j<=n;j++) printf("%d%c",(*v.begin()).f[i][j],j<n?' ':'\n');
else printf("IMPOSSIBLE\n");
}
时间复杂度:$O\left( {2^n mn} \right)$;后面的对所有可行方案的排序,认为能够达成目标的翻转方案远小于 $2^n$,不考虑其时间复杂度)。
POJ 3279 - Fliptile - [状压+暴力枚举]的更多相关文章
- POJ.3279 Fliptile (搜索+二进制枚举+开关问题)
POJ.3279 Fliptile (搜索+二进制枚举+开关问题) 题意分析 题意大概就是给出一个map,由01组成,每次可以选取按其中某一个位置,按此位置之后,此位置及其直接相连(上下左右)的位置( ...
- hihocoder 1829 - 压缩字符串 - [状压+暴力枚举][2018ICPC北京网络预赛B题]
题目链接:https://hihocoder.com/problemset/problem/1829 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Lara Croft, ...
- Gym 101194L / UVALive 7908 - World Cup - [三进制状压暴力枚举][2016 EC-Final Problem L]
题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?opti ...
- POJ 3279 Fliptile(反转 +二进制枚举)
Fliptile Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13631 Accepted: 5027 Descrip ...
- 状态压缩+枚举 POJ 3279 Fliptile
题目传送门 /* 题意:问最少翻转几次使得棋子都变白,输出翻转的位置 状态压缩+枚举:和之前UVA_11464差不多,枚举第一行,可以从上一行的状态知道当前是否必须翻转 */ #include < ...
- POJ 3279(Fliptile)题解
以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定长宽的黑白棋棋盘摆满棋子,每次操作可以反转一个位置和其上下左右共五个位置的棋子的颜色,求要使用最少翻转次数将所有棋子反转为黑 ...
- POJ 3279 Fliptile(翻格子)
POJ 3279 Fliptile(翻格子) Time Limit: 2000MS Memory Limit: 65536K Description - 题目描述 Farmer John kno ...
- [Luogu P3959] 宝藏 (状压DP+枚举子集)
题面 传送门:https://www.luogu.org/problemnew/show/P3959 Solution 这道题的是一道很巧妙的状压DP题. 首先,看到数据范围,应该状压DP没错了. 根 ...
- [NYIST32]组合数(状压,枚举,暴力)
题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=32 求n个数中挑出r个数字的所有情况,最后倒序输出所有情况. 状压枚举所有情况就是了 ...
随机推荐
- 福利:42套AI技术视频免费领取
<福利:33套AI技术视频免费领取> 视频获取方式:请加机器学习和自然语言(QQ群号:436303759)群后,私信群主获取(备注上自己想要获取是视频名称),仅限本群公众号粉丝成员,多套视 ...
- gdb调试常用实用命令和core dump文件的生成(转)
1.生成core dump文件的方法: $ ulimit -c //查看是否为0 如果为0 $ ulimit -c unlimited 这样在程序崩溃以后会在当前目录生成一个core.xxxx的 ...
- SQLServer Always On FCI 脑裂及可疑状态修复
FCI 双节点集群,因为晚上集群节点间的网络中断过.两个节点都觉得还有一个节点宕机,在各节点的集群管理中都看到对方已宕机. 连接到集群IP.提示 msdb 数据库有问题: watermark/2/te ...
- 发现2017年最好的CSS框架
如今,无数的框架出现在定期而少数人喜欢自助,Foundation和angular.js主宰了整个世界的发展.CSS代表用于描述HTML(或XML)文档表示的样式表语言.一个框架被定义为一个包,它由一组 ...
- 分析轮子(九)- Cloneable.java
注:玩的是JDK1.7版本 一:Cloneable.java 接口也是标记接口,所以,它没有任何方法和属性,实现此接口表示的意思是:可以调用 Object.java 类的 clone() 方法,进行简 ...
- Huginn及环境搭建
博客搬迁至https://blog.wangjiegulu.com RSS订阅:https://blog.wangjiegulu.com/feed.xml Huginn 及环境搭建 什么是 Hugin ...
- MMU内存管理单元
arm-linux学习-(MMU内存管理单元) 什么是MMU MMU(Memory Management Unit)主要用来管理虚拟存储器.物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及 ...
- java maven通过SMTP发送QQ邮件的完全步骤
1.首先打开QQ邮箱的SMTP服务,因为QQ邮箱对于一般的用户都是默认关闭SMTP服务的. 找到SMTP服务的选项,可以看到此处默认是关闭的,点击开启,然后腾讯会进行一些身份验证,身份验证通过以后,腾 ...
- 在mysql命令行下执行sql文件
***********在mysql命令行下执行sql文件*********** C:\Windows\system32>cd E:\MySQL\mysql-5.7.16-winx64\bin / ...
- QT信号/槽
在我的理解中,QT和Android都是类似的开发框架,都是由开发团队封装了各式各样的接口和数据结构.将一些问题的解决方法简单化比如QT中将线程封装为QThread,派生类通过重写run方法来将代码投入 ...