POJ.3279 Fliptile (搜索+二进制枚举+开关问题)
POJ.3279 Fliptile (搜索+二进制枚举+开关问题)
题意分析
题意大概就是给出一个map,由01组成,每次可以选取按其中某一个位置,按此位置之后,此位置及其直接相连(上下左右)的位置(如果有)的0变成1,1变成0。现在求需要按多少次,才能使得整个map全部变成0。
此题解法与 UVA.11464 Even Parity 有异曲同工之妙。
首先可以看出,最多每个位置按一次,因为再按的话,相当于没按。如果我们枚举每一个位置是否按的话,2^(n*n)的复杂度爆炸。
接着思考,其实相对来说,下一行是否按,可以根据上一行的情况来决定。举个例子,如果上一行为1,那么下一行是一定要按的,按之后可以让上一行变成0.那么下下一行也是这个道理。
所以可以仅仅枚举第一行,就可以一次判断出来整个棋盘哪个位置按了,哪个没按。
说道这里可见这个题是有开关问题的性质。
至于如何枚举第一行,这里涉及到二进制枚举的方法,有兴趣的读者可以直接看UVA.11464 Even Parity或者从网上找相关资料,这里不再赘述。
需要注意的一点是,要判断最后一行是否全部为0,如果不是白色,说明这种方案不可行。要舍弃。
代码总览
#include <cstdio>
#include <algorithm>
#include <cstring>
#define nmax 20
#define inf 1000000
using namespace std;
int mp[nmax][nmax],flip[nmax][nmax],ans[nmax][nmax];
int spx[5] = {0,0,1,0,-1};
int spy[5] = {0,1,0,-1,0};
int m,n;
int ret = 0;
bool check(int x, int y)
{
if(x>=0 && x <m && y>=0 && y<n) return true;
else return false;
}
int handle(int x, int y)
{
int temp = mp[x][y];
for(int i = 0;i<5;++i){
int nx = x + spx[i];
int ny = y + spy[i];
if(check(nx,ny)){
temp+=flip[nx][ny];
}
}
return temp % 2;
}
int Process()
{
for(int i = 1;i<m;++i){
for(int j = 0;j<n;++j){
if(handle(i-1,j)){
flip[i][j] = 1;
}
}
}
for(int i = 0;i<n;++i){
if(handle(m-1,i)) return inf;
}
int temp = 0;
for(int i = 0;i<m;++i){
for(int j = 0;j<n;++j){
temp+=flip[i][j];
}
}
return temp;
}
void update()
{
for(int i = 0;i<m;++i){
for(int j = 0;j<n;++j){
ans[i][j] = flip[i][j];
}
}
}
int main()
{
while(scanf("%d %d",&m,&n) != EOF){
memset(mp,0,sizeof(mp));
memset(ans,0,sizeof(ans));
for(int i = 0;i<m;++i){
for(int j = 0;j<n;++j)
scanf("%d",&mp[i][j]);
}
ret = inf;
int temp = 0;
for(int i = 0;i<(1<<n);++i){
memset(flip,0,sizeof(flip));
for(int j = 0;j<n;++j){
flip[0][j] = 1&(i>>j);
}
temp = Process();
if(temp < ret){
ret = temp;
update();
}
}
if(ret == inf) printf("IMPOSSIBLE\n");
else{
for(int i = 0;i<m;++i){
for(int j = 0;j<n;++j){
if(j == 0) printf("%d",ans[i][j]);
else printf(" %d",ans[i][j]);
}
printf("\n");
}
}
}
return 0;
}
POJ.3279 Fliptile (搜索+二进制枚举+开关问题)的更多相关文章
- POJ 3279 Fliptile (二进制+搜索)
[题目链接]click here~~ [题目大意]: 农夫约翰知道聪明的牛产奶多. 于是为了提高牛的智商他准备了例如以下游戏. 有一个M×N 的格子,每一个格子能够翻转正反面,它们一面是黑色,还有一面 ...
- (简单) POJ 3279 Fliptile,集合枚举。
Description Farmer John knows that an intellectually satisfied cow is a happy cow who will give more ...
- 状态压缩+枚举 POJ 3279 Fliptile
题目传送门 /* 题意:问最少翻转几次使得棋子都变白,输出翻转的位置 状态压缩+枚举:和之前UVA_11464差不多,枚举第一行,可以从上一行的状态知道当前是否必须翻转 */ #include < ...
- POJ 3279 Fliptile(翻格子)
POJ 3279 Fliptile(翻格子) Time Limit: 2000MS Memory Limit: 65536K Description - 题目描述 Farmer John kno ...
- POJ 3279 Fliptile(反转 +二进制枚举)
Fliptile Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13631 Accepted: 5027 Descrip ...
- poj 3279 Fliptile(二进制搜索)
Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He ha ...
- POJ 3279 Fliptile (二进制枚举)
<题目链接> <转载于 >>> > 题目大意: 给定一个M*N矩阵,有些是黑色(1表示)否则白色(0表示),每翻转一个(i,j),会使得它和它周围4个格变为另 ...
- poj 3279 Fliptile(二进制)
http://poj.org/problem?id=3279 在n*N的矩阵上,0代表白色,1代表黑色,每次选取一个点可以其颜色换过来,即白色变成黑色,黑色变成白色,而且其上下左右的点颜色也要交换,求 ...
- POJ - 3279 Fliptile(反转---开关问题)
题意:有一个M*N的网格,有黑有白,反转使全部变为白色,求最小反转步数情况下的每个格子的反转次数,若最小步数有多个,则输出字典序最小的情况.解不存在,输出IMPOSSIBLE. 分析: 1.枚举第一行 ...
随机推荐
- 我们一起学习WCF 第三篇头消息验证用户身份
前言:今天我主要写的是关于头消息的一个用处验证用户信息 下面我画一个图,可以先看图 第一步:我们先开始做用户请求代码 首先:创建一个可执行的上下文对象块并定义内部传输的通道 using (Operat ...
- 理解学习Springboot(一)
Springboot有何优势呢,网上一大推,这里就不写了. 一.配置maven 1.在maven官网下载maven,http://maven.apache.org/download.cgi 2.将下载 ...
- python-map, reduce, filter, lambda
目录 lambda表达式 reduce()函数 map()函数 filter()函数 tips:以下使用到的迭代器,可迭代对象,生成器等概念可以参见我的另一篇博客 lambda表达式 主要用于一行写完 ...
- smartgit 过期
进入到安装目录把Setting.xml 文件删除然后,再次打开就可以正常使用了.
- html js 全选 反选 全不选源代码
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- mysql5.5 升级到 5.7 的坑
1.大概思路,docker 新启一个mysql5.7 端口映射到3307 2. 导出5.5 的.sql文件,导入5.7中 3.测试通过后,可将5.5关闭.5.7端口改回3306 GRANT ALL P ...
- XSS留言板实现
XSS 留言板实现-笔记 预备知识 XSS漏洞 XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS ...
- python打印图形大全(详解)
,): shixin=chr() print(shixin) -------------------结果:2) for i in range(0,10): shixin=chr(9679) print ...
- CentOS 6.7下创建桌面快捷方式
CentOS 6.7下创建桌面快捷方式如下: 1 在桌面右键,选择“创建启动器" 2 在弹出菜单中,填写名称(显示在桌面上的名字),命令(可执行程序的路径) 3 点击弹出菜单左边的图标,选择 ...
- NSURLErrorDomain错误代码
kCFURLErrorUnknown = -998, kCFURLErrorCancelled = -999, kCFURLErrorBadURL = -1000, kCFURLErrorTimedO ...