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. c#后台代码请求访问api接口

    前言:最近公司项目与外部api接口对接较多 ,写下自己的代码总结.介绍两种访问方式(HttpClient.HttpWebRequest) 一.HttpWebRequest 访问Api private ...

  2. 061 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 08 一维数组总结

    061 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 08 一维数组总结 本文知识点:一维数组总结 总结 注意点

  3. 01 sublime text3下配置c/c++ 的编译运行环境

    安装mingw,在线安装经常出问题,推荐离线安装 参考: https://blog.csdn.net/qq_34432960/article/details/106124496?utm_medium= ...

  4. MATLAB中conv2的详细用法 (以及【matlab知识补充】conv2、filter2、imfilter函数原理)

    转载: 1.https://blog.csdn.net/jinv5/article/details/52874880 2.https://blog.csdn.net/majinlei121/artic ...

  5. rustup命令速度慢

    通过以下命令更换镜像: $ENV:RUSTUP_DIST_SERVER='https://mirrors.ustc.edu.cn/rust-static' $ENV:RUSTUP_UPDATE_ROO ...

  6. css引入本地字体

    1.首先创建一个字体 @font-face { font-family: 'number_font'; //创建一个number_font字体名称 src: url('../../../style/F ...

  7. c 判断端口是否已被使用

    isPortOpen.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include & ...

  8. 使用appium后安卓手机无法调出键盘解决方法

    问题:用appium进行真机调试后,使用手机的app进行输入时无法调出键盘. 原因:appium调试时,将手机输入法设置成了Unicode IME 解决方法: 方法一,手机设置里修改输入法: 不同的手 ...

  9. 【C语言学习笔记】C语言函数执行成功时,返回1和返回0,究竟哪个好?

    基本上,没有人会将大段的C语言代码全部塞入 main() 函数,更好的做法是按照复用率高,耦合性低的原则,尽可能的将代码拆分不同的功能模块,并封装成函数.C语言代码的组合千变万化,因此函数的功能可能会 ...

  10. spring boot:用zxing生成二维码,支持logo(spring boot 2.3.2)

    一,zxing是什么? 1,zxing的用途 如果我们做二维码的生成和扫描,通常会用到zxing这个库, ZXing是一个开源的,用Java实现的多种格式的1D/2D条码图像处理库. zxing还可以 ...