Fliptil(fliptile.pas/c/cpp)

【问题描述】

约翰知道,那些高智力又快乐的奶牛产奶量特别高。所以他做了一个翻瓦片的益智游戏来娱乐奶牛。

在一个M×N的骨架上,每一个格子里都有一个可以翻转的瓦片。瓦片的一面是黑色的,而另一面是白色的。对一个瓦片进行翻转,可以使黑变白,也可以使白变黑。然而,奶牛们的蹄子是如此的巨大而且笨拙,所以她们翻转一个瓦片的时候,与之有公共边的相邻瓦片也都被翻转了。

那么,这些奶牛们最少需要多少次翻转,使所有的瓦片都变成白面向上呢?如果可以做到,输出字典序最小的结果(将结果当成字符串处理),如果不能做到输出"IMPOSSIBLE".

【输入格式】

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

【输出格式】

输出M行,每行N个用空格隔开的整数,表示对应的格子是否进行了翻动,0表示不翻动,1表示翻动。

【输入样例】

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

【数据规模】

对于50%的数据:1≤M,N≤5;

对于70%的数据:1≤M,N≤10;

对于100%的数据:1≤M,N≤15;

看数据范围应该也猜得到是状态压缩+DFS。

一开始直接枚举第一行的状态,即翻或不翻的状态(状压)。

因为如果上一行是1,那么这一格一定要翻。

N^2做一遍即可。

理论复杂度O((2^M)*(N^2))

code:

#include <cstdio>
using namespace std;
char tc(){
static char fl[],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,,,stdin),A==B)?EOF:*A++;
}
int read(){
char c;while(c=tc(),c<''||c>'');int x=c-'';
while(c=tc(),c>=''&&c<='')x=(x<<)+(x<<)+c-'';
return x;
}
int N,M,a[][],t[][],ans[][],w[][],res=2e9;
void rotate(int x,int y){
t[x][y]^=;w[x][y]=;
if(x->=)t[x-][y]^=;if(y->=)t[x][y-]^=;
if(x+<=N)t[x+][y]^=;if(y+<=M)t[x][y+]^=;
}
void check(int wks){
int tk=;
for(int i=;i<=N;i++)for(int j=;j<=M;j++)w[i][j]=,t[i][j]=a[i][j];
for(int i=;i<=M;i++)
if(<<i-&wks){
tk++;if(tk>=res)return ;//如果大于最优解直接return ;
rotate(,M-i+);
}//旋转第一行的(按wks状态旋转)
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
if(t[i-][j]){
tk++;if(tk>=res)return ;
rotate(i,j);
}
for(int j=;j<=M;j++)if(t[N][j])return ;
res=tk;
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)ans[i][j]=w[i][j];
}
void puts(){
for(int i=;i<=N;i++){
for(int j=;j<=M;j++)
printf("%d ",ans[i][j]);
puts("");
}
}
int main(){
freopen("fliptile.in","r",stdin);
freopen("fliptile.out","w",stdout);
N=read(),M=read();
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)a[i][j]=read();
for(int i=;i<(<<M);i++)
check(i);
if(res==2e9)puts("IMPOSSIBLE");
else puts();
}

Fliptil_KEY的更多相关文章

随机推荐

  1. 面试知识整理-Java基础

    三大特征:封装,继承,多态 多态:简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情. 抽象:抽象是将一类对象的共同特征总结出来构造类的过程 包装,可以讲基本类型当做对象来使用,抽象只关心对 ...

  2. [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP叠加图

    关于如何移植在android上使用SDL,可以参考[原]零基础学习SDL开发之移植SDL2.0到Android 和 [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP图 . 在一篇 ...

  3. [原]零基础学习视频解码之FFMpeg中比较重要的函数以及数据结构

    在正式开始解码练习前先了解下关于FFmpeg中比较重要的函数以及数据结构. 1. 数据结构:  (1) AVFormatContext  AVFormatContext是一个贯穿始终的数据结构,很多函 ...

  4. 记两个std接口equal_range,set_difference

    1.equal_range equal_range是C++ STL中的一种二分查找的算法,试图在已排序的[first,last)中寻找value,它返回一对迭代器i和j,其中i是在不破坏次序的前提下, ...

  5. EOJ-3300 奇数统计(高维前缀和)

    题目链接: https://acm.ecnu.edu.cn/problem/3300/ 题目大意: 给n个数,求在n个数中选两个数(可重复),使得这两个数的组合数是奇数,求总共有多少种取法. 解题思路 ...

  6. IntelliJ IDEA中 查看某个类中的所有方法

    方法一:alt + 7 方法二: ctrl + F12 方法三: 自定义 File Structure

  7. Django Url设计 小知识点

    mysite/news/urls.py: from django.conf.urls import url from . import views urlpatterns = [ url(r'^art ...

  8. tmux 后台运行程序

    之前写过tmux分屏,其实这个只是方便写代码啥的,那都还不是最重要的.跑模型时,一般一跑就是一整天都是常事. 电脑关机,睡眠,ssh连接失效都会断了程序运行. solution:tmux后台运行程序! ...

  9. 【[ZJOI2006]物流运输】

    一直不会做,觉得这是一道神题 于是万般无奈下去借鉴抄了一下题解 发现这就是一道套路题 我们用\(dp[i]\)表示前\(i\)天的最小总花费,于是我们就可以用一个常规的老套路来做了 那就是枚举断点 我 ...

  10. 让Git不再难学

    写在前面 在团队做过软件开发的,版本控制必是不可或缺的一项.目前,版本控制主要分为集中式版本控制系统和分布式版本控制系统 ,即大家熟知的SVN和Git.Git是当下最流行的分布式版本控制系统,故,今天 ...