P2346 四子连棋

迭代加深++

题意描述

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

看不懂的话,右手传送门

算法分析

求最小步数,数据范围又那么小,肯定可以用搜索,

那么在bfs/dfs中选一个吧,bfs肯定没问题(OIer都知道),

但dfs的话,你就不知道搜索深度了,所以不能用?

不是的,有一个具有bfs+dfs双重特性的算法:ID****(迭代加深)

  • 什么是迭代加深?百度去吧。
  • bfs和ID哪个快?ID(仅限本题)

知道用什么算法就好办了,但还要注意几个细节:

  1. 题目是黑白棋子交替行走,所以搜索时既可以黑子开局也可以白子开局。
  2. 题目是有2个白格子,要分别搜索。

然后就可以AC了

代码实现

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std; int a[10][10],d=1;
int dx[5]={0,1,-1,0,0};
int dy[5]={0,0,0,1,-1}; bool check(){
for(int i=1;i<=4;i++){
if(a[i][1]==a[i][2]&&a[i][2]==a[i][3]&&a[i][3]==a[i][4]) return true;
if(a[1][i]==a[2][i]&&a[2][i]==a[3][i]&&a[3][i]==a[4][i]) return true;
}
if(a[1][1]==a[2][2]&&a[2][2]==a[3][3]&&a[3][3]==a[4][4]) return true;
if(a[1][4]==a[2][3]&&a[2][3]==a[3][2]&&a[3][2]==a[4][1]) return true;
return false;
} bool dfs(int fx,int fy,int fxx,int fyy,int color,int step){
if(step==d){
if(check()) return true;
return false;
} for(int i=1;i<=4;i++){
int gx=fx+dx[i];
int gy=fy+dy[i];
int gxx=fxx+dx[i];
int gyy=fyy+dy[i];
if(gx>=1&&gx<=4&&gy>=1&&gy<=4&&a[gx][gy]!=color){
swap(a[fx][fy],a[gx][gy]);
if(dfs(gx,gy,fxx,fyy,color==1?2:1,step+1)) return true;
swap(a[fx][fy],a[gx][gy]);
}
if(gxx>=1&&gxx<=4&&gyy>=1&&gyy<=4&&a[gxx][gyy]!=color){
swap(a[fxx][fyy],a[gxx][gyy]);
if(dfs(fx,fy,gxx,gyy,color==1?2:1,step+1)) return true;
swap(a[fxx][fyy],a[gxx][gyy]);
}
}
return false;
} int main(){
int fx1=0,fy1,fx2,fy2;
char ch;
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
cin>>ch;
if(ch=='B') a[i][j]=1;
else if(ch=='W') a[i][j]=2;
else{
if(!fx1){fx1=i;fy1=j;}
else{fx2=i;fy2=j;}
}
}
} /*for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
printf("%d",a[i][j]);
}
printf("\n");
}
printf("%d %d %d %d\n",fx1,fy1,fx2,fy2);*/ while(1){
if(dfs(fx1,fy1,fx2,fy2,1,0)){printf("%d\n",d);break;}
if(dfs(fx1,fy1,fx2,fy2,2,0)){printf("%d\n",d);break;}
d++;
}
return 0;
}

结语

ID

P2346 四子连棋的更多相关文章

  1. 洛谷P2346四子连棋

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

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

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

  3. codevs1004四子连棋[BFS 哈希]

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

  4. Codevs p1004 四子连棋

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

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

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

  6. codevs 1004 四子连棋

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

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

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

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

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

  9. codevs1004四子连棋

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

随机推荐

  1. 042 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 04 案例演示while循环的使用——循环输出英文字母

    042 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 04 案例演示while循环的使用--循环输出英文字母 本文知识点:案例演示while循环的使用2 ...

  2. arduino中SCoop库的简单应用案例

    转载:https://www.csdn.net/gather_27/MtTaggzsMDExMS1ibG9n.html arduino中SCoop库的简单应用案例首先这篇文章来在视频https://v ...

  3. PADS Layout VX.2.3 灌铜之后只显示灌铜外框,没有显示整块铜皮

    操作系统:Windows 10 x64 工具1:PADS Layout VX.2.3 使用Copper Pour功能,画了一个灌铜区,并分配了网络. Tools > Pour Manager,打 ...

  4. spring-boot-route(十)多数据源切换

    前面我们已经介绍了三种方式来操作数据库,在实际开发中,往往会出现一个服务连接多个数据库的需求,这时候就需要在项目中进行灵活切换数据源来完成多个数据库操作.这一章中,我们使用jdbcTemplate来学 ...

  5. 从字节码层次看i++和++i

    关于的Java的i++和++i的区别,初学者可能会混淆,这时候有经验的同学或同事就会告诉你,++在后,就会立马加值, ++在后则会等会儿再加,所以如果i == 0 ,那么i++ == 0,++i == ...

  6. chattr 和 lsattr 命令详解

    lsattr 命令 lsattr 命令用于查看文件的第二扩展文件系统属性. 语法: lsattr(选项)(参数) 选项: -E:可显示设备属性的当前值,但这个当前值是从用户设备数据库中获得的,而不是从 ...

  7. Java防止文件被篡改之文件校验和

    Java防止文件被篡改之文件校验和转载:请注明出处,谢谢! 1.为什么要防止文件被篡改?  答案是显然的,为了保证版权,系统安全性等.之前公司开发一个系统,技术核心是一个科学院院士的研究成果,作为一款 ...

  8. 前端传递的json格式与SpringMVC接收实体类的对应关系

    这篇文章主要是帮助刚刚入行的猿猿尽快适应Restful风格的搬砖生活 @RequestBody注解 基本介绍:@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数 ...

  9. 2440启动流程 <转载>

    韦东山 博客园 首页 订阅 管理 2440启动过程分析   2440启动过程分析 2440启动过程算是一个难点,不太容易理解,而对于2440启动过程的理解,影响了后面裸机代码执行流程的分析,从而看出2 ...

  10. 多测师讲解python _练习题002_高级讲师肖sir

    # 1.求出1/1+1/3+1/5--+1/99的和 # 2.用循环语句,计算2-10之间整数的循环相乘的值. # 3.用for循环打印九九乘法表 # 4.求每个字符串中字符出现的个数如:hellow ...