【codevs1004】四子连棋 状压bfs
题目大意:给定一个大小为 4*4 的棋盘,分别有 7 个黑子、7 个白子和 2 个空位构成,求出至少需要移动多少步,才能使得四个相同的棋子共线。
题解:显然每一种棋盘的局面都是一个状态,因此需要采用状态压缩的搜索。总共的局面最多有4e7种,并且所给的内存足够开下哈希表。
需要注意的是,数据中有很多不是对称的情况,因此需要分别考虑先移动白子和黑子的情况,再取最小值,得到答案。
代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn=5e7;
const int inf=0x3f3f3f3f;
const int dx[]={0,0,-1,1};
const int dy[]={1,-1,0,0};
//b->1 w->0 o->2
char s[10];
int state[5][5],mp[2][maxn],ans=inf,st;
bool col[maxn]; //b->1 w->0
int get_hash(int a[5][5]){
int val=0;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
val=val*3+a[i][j];
return val;
}
void get_state(int val){
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
state[i][j]=val%3,val/=3;
}
void read_and_parse(){
for(int i=1;i<=4;i++){
scanf("%s",s+1);
for(int j=1;j<=4;j++){
if(s[j]=='B')state[i][j]=1;
if(s[j]=='W')state[i][j]=0;
if(s[j]=='O')state[i][j]=2;
}
}
st=get_hash(state);
}
bool right(int x,int y,int cor){
if(x<1||y<1||x>4||y>4||state[x][y]!=cor)return 0;
return 1;
}
bool check(int a[5][5]){
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 1;
if(a[1][i]==a[2][i]&&a[2][i]==a[3][i]&&a[3][i]==a[4][i])return 1;
}
if(a[1][1]==a[2][2]&&a[2][2]==a[3][3]&&a[3][3]==a[4][4])return 1;
if(a[1][4]==a[2][3]&&a[2][3]==a[3][2]&&a[3][2]==a[4][1])return 1;
return 0;
}
void solve(int cor){
queue<int> q;
q.push(st),mp[cor][st]=1,col[st]=cor;
while(q.size()){
int u=q.front();q.pop();
get_state(u);
if(check(state)){ans=min(ans,mp[cor][u]-1);return;}
for(int i=1;i<=4;i++)for(int j=1;j<=4;j++)if(state[i][j]==2){
for(int k=0;k<4;k++){
int nx=i+dx[k],ny=j+dy[k];
if(!right(nx,ny,col[u]))continue;
swap(state[i][j],state[nx][ny]);
int v=get_hash(state);
if(!mp[cor][v])mp[cor][v]=mp[cor][u]+1,col[v]=col[u]^1,q.push(v);
swap(state[i][j],state[nx][ny]);
}
}
}
}
int main(){
read_and_parse();
solve(1);solve(0);
printf("%d\n",ans);
return 0;
}
【codevs1004】四子连棋 状压bfs的更多相关文章
- 【宽度优先搜索】神奇的状态压缩 CodeVs1004四子连棋
一.写在前面 其实这是一道大水题,而且还出在了数据最水的OJ上,所以实际上这题并没有什么难度.博主写这篇blog主要是想写下一个想法--状态压缩.状态压缩在记录.修改状态以及判重去重等方面有着极高的( ...
- codevs1004四子连棋[BFS 哈希]
1004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗 ...
- codevs1004四子连棋
1004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白 ...
- 迭代加深搜索[codevs1004 四子连棋]
迭代加深搜索 一.算法简介 迭代加深搜索是在速度上接近广度优先搜索,空间上和深度优先搜索相当的搜索方式.由于在使用过程中引入了深度优先搜索,所以也可以当作深度优先搜索的优化方案. 迭代加深搜索适用于当 ...
- codevs1004 四子连棋
题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双 ...
- codevs 1004 四子连棋 BFS、hash判重
004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋 ...
- 【洛谷 P2346】四子连棋(状态压缩,搜索)
其实这题可以直接二进制状压做,1表示黑棋,0表示白棋,另外记录下2个空点的位置就行了. 具体看代码(冗长): #include <iostream> #include <cstdio ...
- Codevs p1004 四子连棋
四子连棋 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向 ...
- P2346 四子连棋
P2346 四子连棋 迭代加深++ 题意描述 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋 ...
随机推荐
- Visual Studio 2019 Serial Keys
Visual Studio 2019 Enterprise BF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 Professional NYWVH-HT ...
- Nagios监控系统部署(源码)
1. 概述2. 部署Nagios2.1 创建Nagios用户组2.2 下载Nagios和Nagios-plugin源码2.3 编译安装3. 部署Nagios-plugin3.1 编译安装nagios- ...
- 保留最新N份备份目录脚本
如下所示,在/opt/backup下是备份目录,只需要保留最新的三份备份,在此之前的备份目录都要删除. [root@syslog-ng ~]# cd /opt/backup/ [root@syslog ...
- SCRUM 12.19
我们的爬虫依然存在一些问题,我们决定暂时将大家的工作重心放在爬虫上. 新的任务分配如下 成员 原本任务 新任务 彭林江 落实API 研究美团爬虫 郝倩 研究遍历美团数据方法 研究遍历美团数据方法 牛强 ...
- Android之JSON格式数据解析
查看原文:http://blog.csdn.net/hantangsongming/article/details/42234293 JSON:JavaScript 对象表示法(JavaScript ...
- package.json中的几种依赖注册对象解析
本博文根据官网+google翻译+自己的理解,欢迎指出翻译的不到位的地方. package.json的重要性不言而喻,一直以来对几种依赖注册对象的区别和作用不是很了解,今日一探究竟. dependen ...
- 广商博客冲刺第六七天new
第四五天沖刺傳送門 第一版的網頁已經放到 云服務器(估計快到期了) 傳送門. (不怎么會玩服務器啊..求指教..目前問題如下: 1.我的電腦mysql密碼跟服務器的密碼不一樣..上傳的時候要把代碼里面 ...
- Sprint 冲刺第二阶段之1---5天(上)
11月24号——12月8号,这一个时间段学校的电压不是很稳定,时不时会断电,为了冲刺的完整性,我们商量决定把这一时间段做的事情写成一个连贯的小日记.然后统一在整个时间段一起发出来. 经过一个阶段的努力 ...
- js数组的用法
1.数组 - - 添加元素 arr.push('abc') 向数组尾部添加元素,返回值为数组的长度 arr.unshift('abc') 向数组头部添加元素,返回值为数组的长度 2.数组 - - ...
- 【转】C语言宏高级用法 [总结]
1.前言 今天看代码时候,遇到一些宏,之前没有见过,感觉挺新鲜.如是上网google一下,顺便总结一下,方便以后学习和运用.C语言程序中广泛的使用宏定义,采用关键字define进行定义,宏只是一种简 ...