【DFS练习】-翻棋子-C++
Description
有一个4*4的棋盘,放有16枚棋子。
每个棋子都是一面黑一面白,一开始有的黑面朝上,有的白面朝上。
下面是一个例子,这个例子用文字描述为:
bwbw
wwww
bbwb
bwwb
我们可以任选一个棋子,把它自己和它的相邻棋子(上下左右,如果有的话)翻面。
比如在例子中如果我们选第3行第1列的棋子翻面,布局就变成如下:
bwbw
bwww
wwwb
wwwb
题目
求出能把所有棋子都翻成白色或都黑色的最少的步数。
Input
4行每行4个字符,可能是b(黑)或w(白)
Output
一个数,最少步数。如果无解输出Impossible
Sample Input
bwbw
wwww
bbwb
bwwb
Sample Output
Impossible
这道题目是一道典型的 深搜。我们可以用3个参数记录一种状态:
step,x,y;
step即当前状态已经使用的步数,x,y,记当前正在考虑是否翻面的棋子的坐标,但是把x,y传到下一层有些麻烦…我们需要判断,如果y=4,那么就传给下一层(x+1,1),否则传给下一层(x,y+1),因为这里没有考虑到x是否越界,所以在dfs的拓展之前还要判断if(x==5)return;
代码实现。
代码实现一直是有些麻烦的事情,有些思路不及时打下来的话就可能逐渐消退。
根据题意,搜索的终点是所有棋子都朝向同一面,也就是任意棋子的朝向==第一颗的
那么很轻易可以写下check函数:
bool check()
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
if(mp[i][j]!=mp[1][1])return 0;
}
}
return 1;
}
翻面也可以暴力写出来:
int dir[5][2]={{0,0},{0,1},{0,-1},{1,0},{-1,0}};
void fan(int x,int y)
{
for(int i=0;i<5;i++)
{
int tx=x+dir[i][0],ty=y+dir[i][1];
if(in(tx,ty))mp[tx][ty]=back(mp[tx][ty]);
}
}
顺便把判断越界的写好
bool in(int x,int y)
{
return 1<=x&&x<=4&&1<=y&&y<=4;
}
然后就是核心部分—dfs了。
先贴一个模板:
void dfs()//参数用来表示状态
{
if(到达终点状态)
{
...//根据题意添加
return;
}
if(越界或者是不合法状态)
return;
if(特殊状态)//剪枝
return ;
for(扩展方式)
{
if(扩展方式所达到状态合法)
{
修改操作;//根据题意来添加
标记;
dfs();
(还原标记);
//是否还原标记根据题意
//如果加上(还原标记)就是 回溯法
}
}
}
1.参数
void dfs(int step,int x,int y)
2.终点状态
if(check()){...}
3.不合法状态
if(x==5)return;
4.剪枝
这道题不需要 awa
5.扩展方式
这道题的扩展方式和模板有点不一样,这个只分两种:翻或者是不翻,但是要注意的是,翻之前要给x,y打上标记,翻完了再取消标记,达到回溯的效果!
fan(x,y);
if(y==4)dfs(step+1,x+1,1);
else dfs(step+1,x,y+1);
fan(x,y);
if(y==4)dfs(step,x+1,1);
else dfs(step,x,y+1);
return;
输入的时候最好把原图转换成01矩阵,方便后续操作awa
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
cin>>ch;
if(ch=='b')
{
mp[i][j]=1;
}
else mp[i][j]=0;
}
}
那个布尔类型的ok是来记是否有解的,如果没有就输出Impossible就可以了。
完整代码贴一下还是:
#include<bits/stdc++.h>
using namespace std;
char ch;
int mp[5][5],/*01矩阵*/min_ans=0x3f3f3f3f,dir[5][2]={{0,0},{0,1},{0,-1},{1,0},{-1,0}};
bool ok;
int back/*反面*/(int x)
{
return (x+1)%2;
}
bool in(int x,int y)
{
return 1<=x&&x<=4&&1<=y&&y<=4;
}
bool check()
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
if(mp[i][j]!=mp[1][1])return 0;
}
}
return 1;
}
void fan(int x,int y)
{
for(int i=0;i<5;i++)
{
int tx=x+dir[i][0],ty=y+dir[i][1];
if(in(tx,ty))mp[tx][ty]=back(mp[tx][ty]);
}
}
void dfs(int step,int x,int y)
{
if(check())
{
min_ans=min(min_ans,step);
ok=1;
return;
}
if(x==5)return;
fan(x,y);
if(y==4)dfs(step+1,x+1,1);
else dfs(step+1,x,y+1);
fan(x,y);
if(y==4)dfs(step,x+1,1);
else dfs(step,x,y+1);
return;
}
int main()
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
cin>>ch;
if(ch=='b')
{
mp[i][j]=1;
}
else mp[i][j]=0;
}
}
dfs(0,1,1);
if(!ok)
{
cout<<"Impossible"<<endl;
}
else cout<<min_ans<<endl;
return 0;
}
【DFS练习】-翻棋子-C++的更多相关文章
- poj—1753 (DFS+枚举)
...
- 【dfs基础讲解及例题】
定义 DFS(Depth-First-Search)深度优先搜索算法,是搜索算法的一种. 接下来因为懒得去找大段大段深奥的材料 所以就是一些个人的理解. 所谓深搜,是相对于广搜(只是第一篇)来说的.深 ...
- POJ 1753 位运算+枚举
题意: 给出4*4的棋盘,只有黑棋和白棋,问你最少几步可以使棋子的颜色一样. 游戏规则是:如果翻动一个棋子,则该棋子上下左右的棋子也会翻一面,棋子正反面颜色相反. 思路: 都是暴搜枚举. 第一种方法: ...
- poj-3279 poj-1753(二进制枚举)
题目链接:http://poj.org/problem?id=3279 题目大意: 有一个m*n的棋盘(1 ≤ M ≤ 15; 1 ≤ N ≤ 15),每个格子有两面分别是0或1,每次可以对一个格子做 ...
- [UOJ266]Alice和Bob又在玩游戏
[UOJ266]Alice和Bob又在玩游戏 Tags:题解 作业部落 评论地址 TAG:博弈 题意 不同于树的删边游戏,删掉一个点删去的是到根的路径 题解 这题只和计算\(SG\)有关,博弈的有关内 ...
- POJ1753 Flip Game(位运算+暴力枚举)
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...
- 【题解】射击-C++
Description 不难发现,豆豆能从很多事情中去思考数学,于是豆豆父母决定让他去练习射击,这是项需要集中注意力的运动,相信 能够让豆豆暂时脱离数学.学习射击的第一天就让豆豆产生 了浓厚的兴趣,射 ...
- 1753 -- Flip Game
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 48663 Accepted: 20724 Descr ...
- POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37427 Accepted: 16288 Descr ...
随机推荐
- 程序定义了多个入口点。使用 /main (指定包含入口点的类型)进行编译
原文:请使用/main进行编译,以指定包含入口点类型 在使用VS工具初学C#的时候需要不停的写小程序,觉得每次都新建项目太过麻烦,所以试着把程序写在一个项目下面,结果编译的时候出错了,因为我每个小程序 ...
- chrome 里面js提示Provisional headers are shown错误
参考:http://stackoverflow.com/questions/21177387/caution-provisional-headers-are-shown-in-chrome-debug ...
- CoolFormat(Qt Creator也可管理VC的Project)
http://download.csdn.net/download/akof1314/8457593 https://github.com/akof1314/CoolFormat http://dow ...
- Bokeh 0.9.0dev 发布,交互式可视化库
快速使用Romanysoft LAB的技术实现 HTML 开发Mac OS App,并销售到苹果应用商店中. <HTML开发Mac OS App 视频教程> 土豆网同步更新:http: ...
- git(一)
一.邮件的格式 抄送:需要知道这件事的人 内容: 大家好: 我是xxx,附件内容是我的简历,请查收,有问题可以随时联系我susun|开发工程师电话:1231xxxxx31地址:xxxxxx联系电话(公 ...
- 数据管理工具Flux、Redux、Vuex的区别
目录 为什么要进行数据管理? 怎么有效地进行数据管理? 数据管理工具 1. Flux 2. Redux 3. Vuex 使用数据管理工具的场景 相关资料 主要讲解一下前端为什么需要进行数据管理,有效的 ...
- YARN分析系列之一 -- 总览YARN组件
下图简单明了的描述了hadoop yarn 的功能是如何从 hadoop 中细化出来的. 注:图片来自 https://apprize.info/php/hadoop/9.html Hadoop 从 ...
- 基于python语言的自动化测试中生成html的测试报告时HtmlTestRunner模块常见问题
一.导入了HTMLTestRunner模块,报错:No module named StringIO,在python3.x中确实没有,在第94行引入的名称改成import io,539行要改成self. ...
- 自定义实现一个loghub(或kafka)的动态分片消费者负载均衡?
一般地,像kafka之类的消息中间件,作为一个可以保持历史消息的组件,其消费模型一般是主动拉取方式.这是为了给消费者足够的自由,回滚或者前进. 然而,也正是由于将消费消息的权力交给了消费者,所以,消费 ...
- 了解Kubernetes主体架构(二十八)
前言 Kubernetes的教程一直在编写,目前已经初步完成了以下内容: 1)基础理论 2)使用Minikube部署本地Kubernetes集群 3)使用Kubeadm创建集群 接下来还会逐步完善本教 ...