[Usaco2007 Open]Fliptile 翻格子游戏题解
问题 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".
输入
* 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
输出
* Lines 1..M: Each line contains N space-separated integers, each specifying how many times to flip that particular location.
样例输入
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 翻格子游戏题解的更多相关文章
- 1647: [Usaco2007 Open]Fliptile 翻格子游戏
1647: [Usaco2007 Open]Fliptile 翻格子游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 423 Solved: 173[ ...
- [Usaco2007 Open]Fliptile 翻格子游戏
[Usaco2007 Open]Fliptile 翻格子游戏 题目 Farmer John knows that an intellectually satisfied cow is a happy ...
- 【BZOJ】1647: [Usaco2007 Open]Fliptile 翻格子游戏(暴力)
http://www.lydsy.com/JudgeOnline/problem.php?id=1647 自己太弱...看题解.. 竟然是枚举第一行的放法,,,因为一定要全部变0,所以将前一行1的在这 ...
- [Usaco2007 Open]Fliptile 翻格子游戏 状态压缩
考试想到了状压,苦于T1废掉太长时间,于是默默输出impossible.. 我们知道,一个格子的翻转受其翻转次数和它相邻翻转次数的影响. 由每一个位置操作两次相当于把它翻过来又翻回去,所以答案中每一个 ...
- 【BZOJ 1647】[Usaco2007 Open]Fliptile 翻格子游戏 模拟、搜索
第一步我们发现对于每一个格子,我们只有翻和不翻两种状态,我们发现一旦确定了第一行操作,那么第二行的操作也就随之确定了,因为第一行操作之后我们要想得到答案就得把第一行全部为0,那么第二行的每一个格子的操 ...
- BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子游戏:部分枚举 位运算
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1647 题意: 在一个n*m(1 <= n,m <= 15)的棋盘上,每一个格子 ...
- bzoj 1647: [Usaco2007 Open]Fliptile 翻格子游戏【dfs】
这个可以用异或高斯消元,但是我不会呀我用的暴搜 2的m次方枚举第一行的翻转情况,然后后面的就定了,因为对于一个j位置,如果i-1的j位置需要翻,那么一定要翻i的j,因为这是i-1的j最后翻的机会 按字 ...
- [Usaco2007 Open]Fliptile 翻格子游戏 状压dp
n,m<=15,直接搞肯定不行,考虑一行一行来, 每一行的状态只与三行有关,所以从第一行开始枚举,每一次让下面一行填上他上面那行的坑 最后一行必须要同时满足他自己和他上面那行,否则舍去 #inc ...
- Fliptile 翻格子游戏
问题 B: [Usaco2007 Open]Fliptile 翻格子游戏 时间限制: 5 Sec 内存限制: 128 MB 题目描述 Farmer John knows that an intell ...
随机推荐
- EPPlus导出两千万记录的测试代码
采用导入100w条记录一个文件,然后合并的方式 using System; using System.IO; using OfficeOpenXml; using System.Data; using ...
- 项目中NHibernate问题及解决方法
1.用户代码未处理 NHibernate.QueryException Message=Type mismatch in NHibernate.Criterion.SimpleExpressio ...
- 为什么需要使用Git客户端?(使用msysgit)
Git 是 Linux Torvalds 为了帮助管理 Linux® 内核开发而开发的一个开放源码的版本控制软件.正如所提供的文档中说的一样,“Git 是一个快速.可扩展的分布式版本控制系统,它具有极 ...
- 利用AngularJS实现一个单页应用
看了下angular 的route,用它做个非常简单的单页面应用,记录一下. 顺便说下,好处是,页面改变时不需要刷新,而每个页面都展现不同的数据.尤其在使用模板页的时候,非常方便. 快速使用Roman ...
- 避免用户重复点击按钮(使用Enable:=False,消息繁忙时会有堵塞的问题,只能改用Sleep)
// 现象描述:// 用户点击按钮后程序开始繁忙工作,这时候用户不知道是否成功,就继续点几次// 采用Enalbe = false ... = true的方式发现还会触发点击,分析原因如下 ...
- 关于JDK和JRE的一些总结
一.关于JDK和JRE JDK (Java Development Kit)即java开发工具,包括JER及代码编译器(javac).文档注释器(JavaDoc).代码调试器(Java Debugge ...
- CMake编译如何解决[-Werror,-Wformat-security] 问题
在用Android Studio进行Android开发时,常常采用 java代码调用C++代码,即JNI调用native的开发模式. 在上层build.gradle编译脚本里面可以指定C++代码的编译 ...
- PHP中关于时间、时区、本地时间、UTC时间、GMT时间、时间戳等知识的梳理
在PHP开发中,我们经常会在时间问题上被搞糊涂,比如我们希望显示一个北京时间,但是当我们使用date函数进行输出时,却发现少了8个小时.几乎所有的php猿类都必须对php中几个重要的时间转换等方法进行 ...
- 第四章 .net core做一个简单的登录
项目目标部署环境:CentOS 7+ 项目技术点:.netcore2.0 + Autofac +webAPI + NHibernate5.1 + mysql5.6 + nginx 开源地址:https ...
- 推荐一个高效,易用功能强大的可视化API管理平台
项目管理 提供基本的项目分组,项目管理,接口管理功能 接口管理 友好的接口文档,基于websocket的多人协作接口编辑功能和类postman测试工具,让多人协作成倍提升开发效率 MockServer ...