博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1985 翻转棋
阅读量:5129 次
发布时间:2019-06-13

本文共 2719 字,大约阅读时间需要 9 分钟。

题目描述

农夫约翰知道,聪明的奶牛可以产更多的牛奶。他为奶牛设计了一种智力游戏,名叫翻转棋。

翻转棋可以分成 M × N 个格子,每个格子有两种颜色,一面是黑的,一面是白的。

一旦翻转某个格子,这个格子的颜色就会颠倒。如果把所有的格子都翻成白的,就算奶牛赢

了。然而,奶牛的蹄子很大,一旦它们打算翻转某个格子,这个格子附近(即和这个格子有

公共边)的格子也会被翻转。一直翻来翻去也很无聊,奶牛们想最小化必须翻动的次数。

请帮助奶牛确定翻动的最少次数和具体的翻法。如果最小解有多个,则输出在字典序意义下

最小的那个,如果不可能完成任务,则只要输出一行单词:IMPOSSIBLE。

输入输出格式

输入格式:

第 1 行:两个整数:M 和 N

第 2 ~ M+1 行:第 i+1 行从左到右依次描述了棋盘第 i 行的颜色,共 N 个整数。 1 代

表黑色, 0 代表白色。

输出格式:

第 1 ~ M 行:每行 N 个整数,分别表示在各个格子上翻转的次数。

输入输出样例

输入样例#1:

4 4
1 0 0 1
0 1 1 0
0 1 1 0
1 0 0 1
输出样例#1:
0 0 0 0
1 0 0 1
1 0 0 1
0 0 0 0
说明

·1 ≤ M, N ≤ 15


题解

第一次用markdown写题面感觉很玄学x

一开始以为要枚举每一个点是否翻转,复杂度爆炸exm?

然而事实上一旦第一行确定了,整个棋盘的方案就确定了

于是只需要枚举第一行的翻转方案

然后对于每个方案判断是否可行并且计算最小步数就可以了

这里在判断翻转的时候用了一种玄学思路:

判断当前点是否需要翻转的时候,看一下它上面的那个点的当前状态是否合法

因为上边那个点的上、左、右三个方向都已经确定了

唯一可以改变它的状态的方法是翻转它下边的点,即当前点

所以如果上边的点当前状态为黑,翻转当前点,使上边的点为白

显然这样翻的话对于每个方案除了最后一行之外不会再有别的黑格子

所以只要O(nm)扫一遍整个棋盘,判断最后一行是否有黑格子,若有则不合法

结合枚举第一行方案,总复杂度\(O(2^n*nm)\)

以及只在当前次数比已记录的方案次数小的时候更新答案就可以保证字典序最小(好像是废话

#include
#include
#include
using namespace std;const int N=20,inf=N*N+9;int n,m,a[N][N],c[N][N],cnt,ans=inf,out[N][N];bool solve(){ for(int i=2;i<=n+1;++i) for(int j=1;j<=m;++j){ int f=0; if(i-2>=1)f+=c[i-2][j]; if(j-1>=1)f+=c[i-1][j-1]; f+=c[i-1][j+1]+c[i-1][j]; if((f&1)^a[i-1][j]){if(i==n+1)return false;else c[i][j]=1,++cnt;} } return true;}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j)scanf("%d",&a[i][j]); for(int i=0;i<=(1<
>j-1)&1;if(c[1][m-j+1])++cnt;} if(solve()){ if(cnt

by:wypx


继续把luogu的题解来水

枚举

我们发现当第一行确定下来之后,要满足合法,只能通过改变下一行的情况来使上一行合法.

也就是说,当前行可以不用合法,但是再下一行进行的操作一定可以使当前行合法。
所以当前位置\((x_i,y)\)需要改变的条件就是\((x_{i-1},y)\)在本次操作前是1
这次操作全部合法就是最后一行改变后全是0;
于是就枚举第一行的改变,剩下的行和列就递推出来。
我枚举的方式是二进制(其实是不太会dfs)当前位置需要改变就是当前所在的二进制数是1
判断当前是否改变,只要看当前所枚举的数x and(1<<位置)就可以了

#include
#include
#include
#include
#include
#include
#include
#define ll long longusing namespace std;const int maxn=20;inline int read(){ int an=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while('0'<=ch&&ch<='9'){an=(an<<3)+(an<<1)+ch-'0';ch=getchar();} return an*f;}int n,m,map[maxn][maxn];int Kasumi[maxn][maxn];int remember[maxn][maxn];//输出答案bool change[maxn][maxn];//当前改变的位置int tep=2333333;//当前答案的操作次数inline void kk(){ for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)Kasumi[i][j]=map[i][j]; memset(change,0,sizeof change);}inline void dfs(int prepare){ kk();int tot=0; for(int i=1;i<=m;i++){ if(!prepare)continue; if(prepare&(1<

\(by:s_a_b_e_r\) ←w:自带特效的名字x

转载于:https://www.cnblogs.com/ck666/p/7715035.html

你可能感兴趣的文章
Vue_(组件通讯)子组件向父组件传值
查看>>
STM32单片机使用注意事项
查看>>
js window.open 参数设置
查看>>
032. asp.netWeb用户控件之一初识用户控件并为其自定义属性
查看>>
移动开发平台-应用之星app制作教程
查看>>
leetcode 459. 重复的子字符串(Repeated Substring Pattern)
查看>>
springboot No Identifier specified for entity的解决办法
查看>>
浅谈 unix, linux, ios, android 区别和联系
查看>>
51nod 1428 活动安排问题 (贪心+优先队列)
查看>>
Solaris11修改主机名
查看>>
latex for wordpress(一)
查看>>
如何在maven工程中加载oracle驱动
查看>>
Flask 系列之 SQLAlchemy
查看>>
aboutMe
查看>>
【Debug】IAR在线调试时报错,Warning: Stack pointer is setup to incorrect alignmentStack,芯片使用STM32F103ZET6...
查看>>
一句话说清分布式锁,进程锁,线程锁
查看>>
FastDFS使用
查看>>
服务器解析请求的基本原理
查看>>
[HDU3683 Gomoku]
查看>>
下一代操作系统与软件
查看>>