POJ 3279 Fliptile (二进制枚举)
<题目链接>
<转载于 >>> >
题目大意:
给定一个M*N矩阵,有些是黑色(1表示)否则白色(0表示),每翻转一个(i,j),会使得它和它周围4个格变为另一个颜色,要求翻转最少的点,使得变为全白色的矩阵,输出这个标记了翻转点的矩阵,如果有多个最优解,输出字典序最小的那个矩阵,若没有解,输出IMPOSSIBLE。
解题分析:
由于一个点翻转两次则返回原来的状态,所以最优解每个点最多翻转一次,但是2^(M*N)过大,所以2^N枚举第一行的所有翻转方式(逆字典序枚举),确定一种方式之后第二行也就随之确定了,因为如果第一行处理后没有翻回白色的点:(i,j),必须在第二行(i+1,j)翻回,否则将无法返回。反之第二行其他的点都处理为不翻转,要不然上一行的点会翻回黑色而无法改变。第二行ok后同理解决第三行,以此类推。处理到最后一行如果不是全白就输出IMPOSSIBLE。否则更新结果。
即,用二进制枚举第一行的翻转情况,然后2~n-1行按照上一行的情况来翻转,最后再判断最后一行是否全部为0,如果为0,则记录下翻转次数,随时更新答案。
- #include<cstdio>
- #include<cstring>
- int t[][], tem[][], m[][];
- //这里用一个数组记录翻转次数,再配合原来的点数,就能判断反转后的点数,这里很巧妙
- int M,N,dir[][] = { ,,,,,,-,,,- };
- int get(int x, int y)//获得x,y点的颜色 //它本身的点数,再加上周围四个点反转的次数,就能得到它的真实点数
- {
- int c = t[x][y];
- for (int i = ; i < ; i++)
- {
- int x1 = x + dir[i][], y1 = y + dir[i][];
- c += tem[x1][y1];
- }
- return c % ;
- }
- int cal() //计算2行及之后的,有解返回翻点数,无解返回-1
- {
- for (int i = ; i <= M; i++)
- for (int j = ; j <= N; j++)
- if (get(i - , j) == )
- tem[i][j] = ;
- //得到前n-1行的翻转次数
- for (int i = ; i <= N; i++)
- if (get(M, i))return -; //如果最后一行有一个点不为0,说明枚举的第一行不符合要求s
- int res = ;
- for (int i = ; i <= M; i++)
- for (int j = ; j <= N; j++)
- res += tem[i][j];
- return res; //记录下需要翻转的总次数
- }
- int main()
- {
- int min = -; //次数>0可以这样初始化
- scanf("%d%d", &M, &N);
- for (int i = ; i <= M; i++)
- for (int j = ; j <= N; j++)
- scanf("%d", &t[i][j]);
- for (int i = ; i < ( << N); i++) //枚举第一行的所有情况
- {
- memset(tem, , sizeof(tem)); //初始化翻转数组
- for (int j = ; j <= N; j++)
- tem[][j] = (i >> (j - )) & ; //根据二进制得到第一行的翻转情况,这个技巧一定要掌握
- int num = cal();
- if (num >= && (min< || min>num)) //取情况成立并且总翻转次数最小的
- {
- min = num;
- memcpy(m, tem, sizeof(tem)); //记录下最后的翻转矩阵
- }
- }
- if (min == -)printf("IMPOSSIBLE\n");
- else
- {
- for (int i = ; i <= M; i++)
- for (int j = ; j <= N; j++)
- printf("%d%c", m[i][j], j == N ? '\n' : ' ');
- }
- return ;
- }
2018-08-30
POJ 3279 Fliptile (二进制枚举)的更多相关文章
- poj 3279 Fliptile(二进制)
http://poj.org/problem?id=3279 在n*N的矩阵上,0代表白色,1代表黑色,每次选取一个点可以其颜色换过来,即白色变成黑色,黑色变成白色,而且其上下左右的点颜色也要交换,求 ...
- 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[二进制状压DP]
题目链接[http://poj.org/problem?id=3279] 题意:给出一个大小为M*N(1 ≤ M ≤ 15; 1 ≤ N ≤ 15) 的图,图中每个格子代表一个灯泡,mp[i][j] ...
- POJ - 3279 Fliptile (枚举)
http://poj.org/problem?id=3279 题意 一个m*n的01矩阵,每次翻转(x,y),那么它上下左右以及本身就会0变1,1变0,问把矩阵变成全0的,最小需要点击多少步,并输出最 ...
- POJ 3279 Fliptile【枚举】
题意: 又是农夫和牛的故事...有m*n个黑白块,黑块的背面是白块,白块背面是黑块,一头牛踩一块,则这个块的上下左右的方块都会转动,问至少踩多少块,才会使所有块都变成白色? 分析: 还是开关问题,同样 ...
- POJ.3279 Fliptile (搜索+二进制枚举+开关问题)
POJ.3279 Fliptile (搜索+二进制枚举+开关问题) 题意分析 题意大概就是给出一个map,由01组成,每次可以选取按其中某一个位置,按此位置之后,此位置及其直接相连(上下左右)的位置( ...
- 状态压缩+枚举 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 ...
随机推荐
- luogu P3522 [POI2011]TEM-Temperature
这道题暴力做法就是枚举每个起点,然后向后拓展到不能拓展 就像这样(红框是每个位置的取值范围,绿线是你取的值构成的折线) 应该可以发现,左端点往右移的过程中,右端点也只能不动或往右移,所以我们可以每次移 ...
- JS的call方法的作用解释,简单易懂
先看看关于call()的官方解释,“调用一个对象的一个方法,以另一个对象替换当前对象.”,看了这样的解释,或许让你更摸不着头脑了.看例子: var x = "我是全局变量"; // ...
- 从前端和后端两个角度分析jsonp跨域访问(完整实例)
一.什么是跨域访问 举个栗子:在A网站中,我们希望使用Ajax来获得B网站中的特定内容.如果A网站与B网站不在同一个域中,那么就出现了跨域访问问题.你可以理解为两个域名之间不能跨过域名来发送请求或者请 ...
- 【转】Python数据类型之“集合(Sets)与映射(Mapping)”
[转]Python数据类型之“集合(Sets)与映射(Mapping)” 一.集合类型(Sets) 集合对象是不同的(不可重复)hashable对象的无序集合.常见用法包括:成员关系测试.移除序列中的 ...
- YOLO(v1)
<You Only Look once:Unified,Real-Time Object Dectection> 以前的图像检测网络其实都是在分类网络的基础上进行修改,而YoLo是将检测问 ...
- ubuntu 下 teamview 取消自动启动 autostart
sudo teamviewer daemon disable
- C/C++杂记:深入虚表结构
1. 虚表与“虚函数表” 在“C/C++杂记:虚函数的实现的基本原理”一文中曾提到“虚函数表”的概念,只是为了便于理解,事实是:虚函数表并不真的独立存在,它只是虚表(virtual table)中的一 ...
- Go语言规格说明书 之 内建函数(Built-in functions)
go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...
- idea开发swing(二)
闲话少说,书接idea开发swing(一). 程序编译完成后,需要打包发布,如果有fat_jar的同学可以通过该插件打包,这里是使用ant来打包,步骤如下: 一.编写build.xml <?xm ...
- bzoj1036点权模板题
/* HYSBZ1036 树上有1-n个结点,每个节点都有一个权值w 操作 CHANGE u t:把结点u的权值改为t QMAX u v:询问从点u到v的路径上的节点的最大权值 QSUM u v:询问 ...