问题 B: [Usaco2007 Open]Fliptile 翻格子游戏

时间限制: 5 Sec  内存限制: 128 MB

题目描述

Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in which they manipulate an M x N grid (1 <= M <= 15; 1 <= N <= 15) of square tiles, each of which is colored black on one side and white on the other side. As one would guess, when a single white tile is flipped, it changes to black; when a single black tile is flipped, it changes to white. The cows are rewarded when they flip the tiles so that each tile has the white side face up. However, the cows have rather large hooves and when they try to flip a certain tile, they also flip all the adjacent tiles (tiles that share a full edge with the flipped tile). Since the flips are tiring, the cows want to minimize the number of flips they have to make. Help the cows determine the minimum number of flips required, and the locations to flip to achieve that minimum. If there are multiple ways to achieve the task with the minimum amount of flips, return the one with the least lexicographical ordering in the output when considered as a string. If the task is impossible, print one line with the word "IMPOSSIBLE".

 约翰知道,那些高智力又快乐的奶牛产奶量特别高.所以他做了一个翻瓦片的益智游戏来娱乐奶牛.在一个M×N(1≤M,N≤15)的骨架上,每一个格子里都有一个可以翻转的瓦片.瓦片的一面是黑色的,而另一面是白色的.对一个瓦片进行翻转,可以使黑变白,也可以使白变黑.然而,奶牛们的蹄子是如此的巨大而且笨拙,所以她们翻转一个瓦片的时候,与之有公共边的相邻瓦片也都被翻转了.那么,这些奶牛们最少需要多少次翻转,使所有的瓦片都变成白面向上呢?如杲可以做到,输出字典序最小的结果(将结果当成字符串处理).如果不能做到,输出“IMPOSSIBLE”.

输入

* Line 1: Two space-separated integers: M and N

* Lines 2..M+1: Line i+1 describes the colors (left to right) of row i of the grid with N space-separated integers which are 1 for black and 0 for white

    第1行输入M和N,之后M行N列,输入游戏开始时的瓦片状态.0表示白面向上,1表示黑面向上.

输出

* Lines 1..M: Each line contains N space-separated integers, each specifying how many times to flip that particular location.

    输出M行,每行N个用空格隔开的整数,表示对应的格子进行了多少次翻转.

样例输入

4 4
1 0 0 1
0 1 1 0
0 1 1 0
1 0 0 1

样例输出

0 0 0 0
1 0 0 1
1 0 0 1
0 0 0 0 OUTPUT DETAILS: After flipping at row 2 column 1, the board will look like:
0 0 0 1
1 0 1 0
1 1 1 0
1 0 0 1 After flipping at row 2 column 4, the board will look like:
0 0 0 0
1 0 0 1
1 1 1 1
1 0 0 1 After flipping at row 3 column 1, the board will look like:
0 0 0 0
0 0 0 1
0 0 1 1
0 0 0 1 After flipping at row 3 column 4, the board will look like:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0 Another solution might be:
0 1 1 0
0 0 0 0
0 0 0 0
0 1 1 0
but this solution is lexicographically higher than the solution above.

  考试第二题,由于有IMPOSSIBLE保底分,果断先做第三题,结果打完发现连IMPOSSIBLE都没时间打了,

/(ㄒoㄒ)/~~,借祥子的一句话,我招谁惹谁了!

  这道题先膜一下QTY_大佬,给我讲明白了,首先这道题一定是搜索,应该不用解释吧,那么这道题最棘手的是我把它翻过来它又会把相邻的几个翻过去,这就会是一个不断绕的过程了,莫名想到了网络流“王者之剑”,于是每个人都会有一个愿望,他如果每次只翻动一个格子就好了,于是乎我们可以注意到我每翻一个格子它的上下层只改变一个,那我们能否利用这个特性去搞他呢,答案是肯定的。

  由于是搜索题,我们不必去管每一次搜索是否一定对,而是去试暴力,那我们便可去枚举第一行我怎么翻,因为第一行翻法确定之后就可以采取近似贪心的策略,挨行去翻,只要上一行同一列的位置为1,我就翻它所对应的本行的位置知道最后一行,只要在最后加一个判断,去判断它最后一行是否都为0,是的话就是可行解,是的,可行解,因为题目要求字典序最小,这个我们待会再说,那我们怎么枚举第一行的翻法呢,感谢QTY_,状压就可以了,时间复杂度也是很好算的,状压是2^15,枚举就是枚举每个格子,最大才225,没毛病。

  那么我们再来解释下字典序这个烦人的东西,说实在的,题目给的字典序到底是怎么来的只能自己推,由样例和注释可知,即使1的个数一样也是有区别的,那么观察可发现样例输出的第一个1位置比注释中的解靠前,因此可以大胆的猜测可以以进制的思想去搞它。

  但这道题还没完,细心的人可能会发现本题中并未保证每个格子翻动次数只为1或0,也就是说每个格子在解中可能翻动了好几次,而按照上面的说法貌似只有0和1,是不是欺负数据水呢?当然不是假设有一种解为:

              0 1

              2 0

那么它完全等价为

              0 1

              0 0

以此类推,大于1只是可行解,不是最优解。

  

 #include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,b[][];
int a[][],an[][];
int mn=0x7fffffff,mi,ans[][];
void dfs(int x){
memset(an,,sizeof(an));
memcpy(b,a,sizeof(a));
for(int i=;i<=n;i++)
{
if((<<(i-))&x)
{
an[][i]=;
b[][i]^=;
b[][i-]^=;
b[][i+]^=;
b[][i]^=;
}
}
for(int i=;i<=m;i++)
{
for(int j=;j<=n;j++)
{
if(b[i-][j])
{
an[i][j]=;
b[i-][j]^=;
b[i][j]^=;
b[i][j-]^=;
b[i][j+]^=;
b[i+][j]^=;
}
}
}
bool yx=;
for(int i=;i<=n;i++)
{
if(b[m][i])
{
yx=;
break;
}
} if(yx)
{ int js=,be=;
for(int i=;i<=m;i++)
{
for(int j=;j<=n;j++)
{
if(an[i][j])
{
js++;
if(!be)
be=(i-)*+j;
}
}
}
if(js<mn)
{
mn=js;
mi=be;
memcpy(ans,an,sizeof(an));
}
else if(js==mn&&be<mi)
{
mi=be;
memcpy(ans,an,sizeof(an));
}
}
}
int main(){
scanf("%d%d",&m,&n);
for(int i=;i<=m;i++)
{
for(int j=;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}
for(int i=;i<(<<n);i++)
{
dfs(i);
}
if(mn==0x7fffffff)
{
printf("IMPOSSIBLE\n");
}
else
{
for(int i=;i<=m;i++)
{
for(int j=;j<=n;j++)
printf("%d ",ans[i][j]);
printf("\n");
}
}
return ;
}

[Usaco2007 Open]Fliptile 翻格子游戏题解的更多相关文章

  1. 1647: [Usaco2007 Open]Fliptile 翻格子游戏

    1647: [Usaco2007 Open]Fliptile 翻格子游戏 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 423  Solved: 173[ ...

  2. [Usaco2007 Open]Fliptile 翻格子游戏

    [Usaco2007 Open]Fliptile 翻格子游戏 题目 Farmer John knows that an intellectually satisfied cow is a happy ...

  3. 【BZOJ】1647: [Usaco2007 Open]Fliptile 翻格子游戏(暴力)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1647 自己太弱...看题解.. 竟然是枚举第一行的放法,,,因为一定要全部变0,所以将前一行1的在这 ...

  4. [Usaco2007 Open]Fliptile 翻格子游戏 状态压缩

    考试想到了状压,苦于T1废掉太长时间,于是默默输出impossible.. 我们知道,一个格子的翻转受其翻转次数和它相邻翻转次数的影响. 由每一个位置操作两次相当于把它翻过来又翻回去,所以答案中每一个 ...

  5. 【BZOJ 1647】[Usaco2007 Open]Fliptile 翻格子游戏 模拟、搜索

    第一步我们发现对于每一个格子,我们只有翻和不翻两种状态,我们发现一旦确定了第一行操作,那么第二行的操作也就随之确定了,因为第一行操作之后我们要想得到答案就得把第一行全部为0,那么第二行的每一个格子的操 ...

  6. BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子游戏:部分枚举 位运算

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1647 题意: 在一个n*m(1 <= n,m <= 15)的棋盘上,每一个格子 ...

  7. bzoj 1647: [Usaco2007 Open]Fliptile 翻格子游戏【dfs】

    这个可以用异或高斯消元,但是我不会呀我用的暴搜 2的m次方枚举第一行的翻转情况,然后后面的就定了,因为对于一个j位置,如果i-1的j位置需要翻,那么一定要翻i的j,因为这是i-1的j最后翻的机会 按字 ...

  8. [Usaco2007 Open]Fliptile 翻格子游戏 状压dp

    n,m<=15,直接搞肯定不行,考虑一行一行来, 每一行的状态只与三行有关,所以从第一行开始枚举,每一次让下面一行填上他上面那行的坑 最后一行必须要同时满足他自己和他上面那行,否则舍去 #inc ...

  9. Fliptile 翻格子游戏

    问题 B: [Usaco2007 Open]Fliptile 翻格子游戏 时间限制: 5 Sec  内存限制: 128 MB 题目描述 Farmer John knows that an intell ...

随机推荐

  1. Android项目实战(四十):在线生成按钮Shape的网站

    原文:Android项目实战(四十):在线生成按钮Shape的网站 AndroidButton Make  右侧设置按钮的属性,可以即时看到效果,并即时生成对应的.xml 代码,非常高效(当然熟练的话 ...

  2. SQL Server 可更新订阅中有行筛选的同步复制移除项目而不重新初始化所有订阅!

    原文:SQL Server 可更新订阅中有行筛选的同步复制移除项目而不重新初始化所有订阅! 在可更新订阅的同步复制中,有行筛选的项目表,移除的时候会提示重新初始化所有的快照并且应用此快照,这将导致所有 ...

  3. UWP入门(二) -- 基础笔记

    原文:UWP入门(二) -- 基础笔记 不错的UWP入门视频,1092417123,欢迎交流 UWP-04 - What i XMAL? XAML - XML Syntax(语法) ,create i ...

  4. CSS3 GENERATOR可以同时为一个元素完成border-radius、box-shadow、gradient和opacity多项属性的设置

    CSS3 GENERATOR可以同时为一个元素完成border-radius.box-shadow.gradient和opacity多项属性的设置 CSS3 GENERATOR 彩蛋爆料直击现场 CS ...

  5. Elasticsearch ML

    Elastic公司在收购了Prelert半年之后,终于在Elasticsearch 5中推出了Machine Learning功能.Prelert本身就擅长做时序性数据的异常检测,从这点上讲也比较契合 ...

  6. VMware 克隆linux后找不到eth0(学习hadoop,所以想快速搭建一个集群)

    发生情况:      由于在学习hadoop,所以想快速搭建一个集群出来.所以直接在windows操作系统上用VMware安装了CentOS操作系统,配置好hadoop开发环境后,采用克隆功能,直接克 ...

  7. web.congfig 禁用 ViewState Session

    <!--禁用 ViewState Session--> <pages enableViewState="false" enableSessionState=&qu ...

  8. abp(net core)+easyui+efcore仓储系统——展现层实现增删改查之控制器(六)

    abp(net core)+easyui+efcore仓储系统目录 abp(net core)+easyui+efcore仓储系统——ABP总体介绍(一) abp(net core)+easyui+e ...

  9. Exceptionless(二) - 使用进阶

    Exceptionless(二) - 使用进阶 作者:markjiang7m2 原文地址:https://www.cnblogs.com/markjiang7m2/p/11100563.html 官网 ...

  10. Spring Boot:实现MyBatis动态创建表

    综合概述 在有些应用场景中,我们会有需要动态创建和操作表的需求.比如因为单表数据存储量太大而采取分表存储的情况,又或者是按日期生成日志表存储系统日志等等.这个时候就需要我们动态的生成和操作数据库表了. ...