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. webpack学习(五)配置详解

    配置详解 //使用插件html-webpack-plugin打包合并html //使用插件extract-text-webpack-plugin打包独立的css //使用UglifyJsPlugin压 ...

  2. boost::intrusive_ptr原理介绍

    boost::intrusive_ptr一种“侵入式”的引用计数指针,它实际并不提供引用计数功能,而是要求被存储的对象自己实现引用计数功能,并提供intrusive_ptr_add_ref和intru ...

  3. Django 模型中FileField字段

    FileField¶ class FileField([upload_to=None, max_length=100, **options])¶ 一个上传文件的字段. 注意 FileField字段不支 ...

  4. Adobe flash player 因过期而遭到阻止解决办法

    最近使用谷歌浏览器时总是提示Adobe flash player 因过期而遭到阻止,这让人很头痛,基本上就是打开一个网页就会弹出一个提示,下面是解决办法. 问题的截图界面: 解决方法:在chrome浏 ...

  5. 【[USACO12DEC]第一!First!】

    一个串不能成为第一的情况有两种 另外一个单词是它的前缀 在分配字母表大小关系的时候出现了矛盾的情况 第一种很好判断,一旦我们在一个单词没有匹配完之前遇到一个结束标志,那么就说明另外一个单词是它的前缀 ...

  6. 2018 Multi-University Training Contest 4 Problem J. Let Sudoku Rotate 【DFS+剪枝+矩阵旋转】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6341 Problem J. Let Sudoku Rotate Time Limit: 2000/100 ...

  7. [19/04/05-星期五] 多线程_Thread(线程、线条)、基本术语

    一.基本概念 多线程是Java语言的重要特性,大量应用于网络编程.服务器端程序的开发,最常见的UI界面底层原理.操作系统底层原理都大量使用了多线程. 我们可以流畅的点击软件或者游戏中的各种按钮,其实, ...

  8. 视图 b

  9. PAT——1010. 一元多项式求导

    设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为n*xn-1.) 输入格式:以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. 输出格式:以与 ...

  10. HDU 2092 (将表达式变成一元二次方程形式)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2092 整数解 Time Limit: 1000/1000 MS (Java/Others)    Me ...