题目描述 Description

在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。

 
 
输入描述 Input Description
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出描述 Output Description

用最少的步数移动到目标棋局的步数。

样例输入 Sample Input

BWBO
WBWB
BWBW
WBWO

样例输出 Sample Output

5

思路:(迭代加深搜索是限制的搜索深度的深搜,可以用来求解大部分的广度优先搜索的题目,不过要确定好搜索的起点和终点)

    首先介绍一下迭代加深搜索:  迭代加深搜索就是在DFS时给定一个深度上限,当搜索深度超过上限时就不再拓展。从1开始枚举深度上限如果能找到解,这个上限就是最优解,否则就加大上限继续搜索。

    现在我们来看这道题:由于黑白两色需要轮流动棋,在搜索时还要记录上一手是哪个颜色的棋移动,判断时也要注意这一点,开始搜索时也要考虑黑先手和白先手两种情况所以DFS时需要存储的状态有:两个空格的坐标,上一手棋的颜色和当前的深度。然后只要想到棋的移动等于空格的移动这一点即可。

代码如下:

 #include<iostream>
#include<cstring> using namespace std;
int map[][];//棋盘
int ox1=,oy1=,ox2=,oy2=,dep;
bool flag=false;
int movex[]={,,,-,},movey[]={,,,,-};
bool ava(int x,int y,int pre)//判断下一步棋是否可以走
{
if(map[x][y]!=pre&&x>=&&x<=&&y>=&&y<=)
return true;
return false;
}
bool win()//判断是否走出了输赢
{
for(int i=;i<=;i++)//水平和垂直方向
{
if(map[i][]==map[i][]&&map[i][]==map[i][]&&map[i][]==map[i][])
return true;
if(map[][i]==map[][i]&&map[][i]==map[][i]&&map[][i]==map[][i])
return true;
}//以下是两个斜对角线
if(map[][]==map[][]&&map[][]==map[][]&&map[][]==map[][])
return true;
if(map[][]==map[][]&&map[][]==map[][]&&map[][]==map[][])
return true; return false;
} void iddfs(int x,int y,int p,int q,int pre,int step)//pre为棋盘的棋子类型,step为搜索深度即所走的步数
{
int nx,ny,qx,qy;
if(win())
{
flag=true;
return ;
}
else if(step>dep)//如果当前深度超过了限制的深度 就停止
return;
for(int i=;i<=;i++)
{
nx=x+movex[i];//分别向四个方向移动
ny=y+movey[i];
qx=p+movex[i];
qy=q+movey[i]; if(ava(nx,ny,pre))//以其中一个空格为起点
{
swap(map[x][y],map[nx][ny]);//交换空格和所移动的棋子
iddfs(nx,ny,p,q,map[x][y],step+);
swap(map[x][y],map[nx][ny]);
}
if(ava(qx,qy,pre))//以另一个空格为起点
{
swap(map[p][q],map[qx][qy]);
iddfs(x,y,qx,qy,map[p][q],step+);
swap(map[p][q],map[qx][qy]);
}
} } int main()
{
char s;
for(int i=;i<=;i++)//对输入的棋盘进行处理
for(int j=;j<=;j++)
{
cin>>s;
if(s=='B')
map[i][j]=;
else if(s=='W')
map[i][j]=;
else
{
map[i][j]=;
if(!ox1)
{
ox1=i;
oy1=j;
}
else
{
ox2=i;
oy2=j;
}
}
}
for(dep=;;dep++)//dep为搜索的限制程度
{
iddfs(ox1,oy1,ox2,oy2,,);
iddfs(ox1,oy1,ox2,oy2,,);
if(flag)
{
cout<<dep<<endl;
break;
}
}
return ;
}

Codevs 四子连棋 (迭代加深搜索)的更多相关文章

  1. codevs 2541 幂运算(迭代加深搜索)

    /* 一开始想到了简单的深搜 维护当前可用的mi数组 然后回溯用哪个 不断更新新产生的mi 这样的问题是 由于mi不断产生 搜索规模扩大 不好 不好 下面是奇丑的WA掉的代码 做个反面教材 */ #i ...

  2. P2346 四子连棋

    P2346 四子连棋 迭代加深++ 题意描述 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋 ...

  3. 迭代加深搜索[codevs1004 四子连棋]

    迭代加深搜索 一.算法简介 迭代加深搜索是在速度上接近广度优先搜索,空间上和深度优先搜索相当的搜索方式.由于在使用过程中引入了深度优先搜索,所以也可以当作深度优先搜索的优化方案. 迭代加深搜索适用于当 ...

  4. 【宽度优先搜索】神奇的状态压缩 CodeVs1004四子连棋

    一.写在前面 其实这是一道大水题,而且还出在了数据最水的OJ上,所以实际上这题并没有什么难度.博主写这篇blog主要是想写下一个想法--状态压缩.状态压缩在记录.修改状态以及判重去重等方面有着极高的( ...

  5. 迭代加深搜索 codevs 2541 幂运算

    codevs 2541 幂运算  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 从m开始,我们只需要6次运算就可以计算出 ...

  6. Codevs p1004 四子连棋

                          四子连棋 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向 ...

  7. codevs 1004 四子连棋

    1004 四子连棋  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold     题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白 ...

  8. codevs 1004 四子连棋 BFS、hash判重

    004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold       题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋 ...

  9. 【洛谷 P2346】四子连棋(状态压缩,搜索)

    其实这题可以直接二进制状压做,1表示黑棋,0表示白棋,另外记录下2个空点的位置就行了. 具体看代码(冗长): #include <iostream> #include <cstdio ...

随机推荐

  1. iOS9新系统下App Store应用上传新指南

    http://www.cocoachina.com/appstore/20151010/13691.html 最近频繁收到小伙伴们的反馈,说经过前期学习已对ASO规则略有了解,但APP的提交审核是由技 ...

  2. oracle-Mount

    执行nomount的所有工作,另外附加数据结构并与这些数据结构进行交互.这时,oracle从控制文件中获得信息. 可以执行的任务是: 执行数据库的完全恢复操作 重命名数据文件 改变数据库的归档状态. ...

  3. PB 级数据处理挑战,Kubernetes如何助力基因分析?

    摘要: 一家大型基因测序功能公司每日会产生 10TB 到 100TB 的下机数据,大数据生信分析平台需要达到 PB 级别的数据处理能力.这背后是生物科技和计算机科技的双向支撑:测序应用从科研逐步走向临 ...

  4. USACO93网络流入门Drainage Ditches 排水渠(DCOJ 5130)

    题目描述 (传送门:http://poj.org/problem?id=1273翻译 by sxy(AFO的蒟蒻)) 每次约翰的农场下雨,Bessie的水池里的四叶草就会被弄破.这就意味着,这些四叶草 ...

  5. ubuntu 使用glfw.h 出现函数无法调用

    最近在学习在Ubuntu下使用qt进行opengl开发,使用到了glfw这个库.我安装官网的编译和安装方法进行了配置安装,在usr/local/include的下产生了glfw.h文件. 于是我在我的 ...

  6. docker查看运行容器详细信息

    使用docker ps命令可以查看所有正在运行中的容器列表, 使用docker inspect命令我们可以查看更详细的关于某一个容器的信息. $ docker inspect 容器id/image

  7. javascript内置函数

    1.Date:日期函数属性(1):constructor 所修立对象的函数参考prototype 能够为对象加进的属性和方法办法(43):getDay() 返回一周中的第几天(0-6)getYear( ...

  8. Python两个字典键同值相加的几种方法

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/Jerry_1126/article/de ...

  9. Java8 Date与LocalDate互转

    Java8 日期时间API,新增了LocalDate.LocalDateTime.LocalTime等线程安全类,接下来要说的是LocalDate与java.util.Date之间的转换. 1.Loc ...

  10. js获取本周日期

    JS获取到本周的日期 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...