codevs1004四子连棋[BFS 哈希]
1004 四子连棋
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● | ○ | ● | |
○ | ● | ○ | ● |
● | ○ | ● | ○ |
○ | ● | ○ |
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
用最少的步数移动到目标棋局的步数。
BWBO
WBWB
BWBW
WBWO
5
很像八数码问题,状态空间搜索
保存State一个二维数组,本次选的颜色,步数,(封装一个结构体也可以),BFS就行了,每次从空白走
hash表来判重
手写队列一个好处是可以直接用队列的编号
PS:1从hzwer那里学了些命名
2据说迭代加深也可以,感觉并不好写
//
// main.cpp
// codevs1004
//
// Created by Candy on 9/29/16.
// Copyright © 2016 Candy. All rights reserved.
// #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=,MAXN=1e6,MOD=,hashsize=2e5;
typedef int State[N][N];
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x;
}
int dx[]={,,,-},dy[]={,-,,},ans=-;
char s[N];
State q[MAXN];
int head=,tail=,d[MAXN],col[MAXN];
bool equ(char a,char b,char c,char d){
if(a!=b||b!=c||c!=d) return false;
return true;
}
bool check(State &a){
for(int i=;i<=;i++){
if(equ(a[i][],a[i][],a[i][],a[i][])) return ;
if(equ(a[][i],a[][i],a[][i],a[][i])) return ;
}
if(equ(a[][],a[][],a[][],a[][]))return ;
if(equ(a[][],a[][],a[][],a[][]))return ;
return ;
}
bool valid(int x,int y,int num){
if(x<||x>||y<||y>) return ;
if(q[num][x][y]!=col[num]) return ;
return ;
}
int h[hashsize],ne[hashsize];
void init(){memset(h,,sizeof(h));}
int gethash(State &s){
int x=;
for(int i=;i<=;i++){
for(int j=;j<=;j++) x=x*+s[i][j];
x%=MOD;
}
return x;
}
bool tti(int num){
int x=gethash(q[num]);
for(int i=h[x];i;i=ne[i])
if(memcmp(q[i],q[num],sizeof(q[num]))==) return ;
ne[num]=h[x];
h[x]=num;
return ;
}
void move(int x,int y){
State &s=q[head];
for(int i=;i<;i++){
int nx=x+dx[i],ny=y+dy[i];
if(!valid(nx,ny,head)) continue;
State &t=q[++tail];
memcpy(t,s,sizeof(s));
swap(t[nx][ny],t[x][y]);
if(tti(tail)){
d[tail]=d[head]+;
col[tail]=col[head]==?:;
}
else tail--;
if(check(t)) ans=d[tail];
}
}
void bfs(){
while(head<=tail){
State &now=q[head]; //printf("head %d\n",head);
for(int i=;i<=;i++)
for(int j=;j<=;j++)
if(now[i][j]==) move(i,j);
if(ans!=-) return;
head++;
}
}
int main(int argc, const char * argv[]) {
State &a=q[++tail],&b=q[++tail];
for(int i=;i<=;i++){
scanf("%s",s+);
for(int j=;j<=;j++){
if(s[j]=='B') a[i][j]=b[i][j]=;
else if(s[j]=='W') a[i][j]=b[i][j]=;
else if(s[j]=='O') a[i][j]=b[i][j]=;
}
}
col[]=;col[]=;
bfs();
printf("%d",ans);
return ;
}
codevs1004四子连棋[BFS 哈希]的更多相关文章
- 【宽度优先搜索】神奇的状态压缩 CodeVs1004四子连棋
一.写在前面 其实这是一道大水题,而且还出在了数据最水的OJ上,所以实际上这题并没有什么难度.博主写这篇blog主要是想写下一个想法--状态压缩.状态压缩在记录.修改状态以及判重去重等方面有着极高的( ...
- codevs 1004 四子连棋 BFS、hash判重
004 四子连棋 时间限制: 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 p1004 四子连棋
四子连棋 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向 ...
- 【洛谷 P2346】四子连棋(状态压缩,搜索)
其实这题可以直接二进制状压做,1表示黑棋,0表示白棋,另外记录下2个空点的位置就行了. 具体看代码(冗长): #include <iostream> #include <cstdio ...
- P2346 四子连棋
P2346 四子连棋 迭代加深++ 题意描述 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋 ...
- codevs 1004 四子连棋
1004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白 ...
随机推荐
- CSS3文本温故
1.CSS早期属性,分为三大类:字体.颜色和文本: 2.CSS文本类型有11个属性: 注:还有一个颜色属性:color,主要用来设置文本颜色 3.CSS3文本阴影属性:text-shadow语法:te ...
- Hybrid框架UI重构之路:二、事出有因
上文回顾:Hybird框架UI重构之路:一.师其长技以自强 一切的重构都是有原因的,或许为了更快速度.更好体验.更快捷开发等,于是就有了自己的开发目标,简单看看未重构前UI("中国移动式&q ...
- jQuery.clean()方法源码分析(一)
在jQuery 1.7.1中调用jQuery.clean()方法的地方有三处,第一次就是在我之前的随笔分析jQuery.buildFramgment()方法里面的,其实还是构造函数的一部分,在处理诸如 ...
- ie8不兼容rgba的解决
借鉴................. 在调试ie8兼容性的问题时,发现ie8不支持rgba. 关于rgba(),即为颜色设置的方法函数,rgb代表颜色,a代表透明度. 如rgba(0,0,0,0.1 ...
- Snort - 配置文件
Snort.conf 版本 2.9.8.3 编译可用选项: --enable-gre --enable-mpls --enable-targetbased --enable-ppm --enable- ...
- 国内最全最详细的hadoop2.2.0集群的HA高可靠的最简单配置
简介 hadoop中的NameNode好比是人的心脏,非常重要,绝对不可以停止工作.在hadoop1时代,只有一个NameNode.如果该NameNode数据丢失或者不能工作,那么整个集群就不能恢复了 ...
- Swift设置自动行高
// 设置行高自适应 tableView.rowHeight = UITableViewAutomaticDimension // 设置预估行高 tableView.estimatedRowHeigh ...
- Android Studio 2.2新功能预览
升级SDK可用Background 多加了个按钮,可用一边写代码一边下载SDK Instant Run 修改代码一秒启动 APK analyzer 分析任何的APK 查看APK下载包的大小,解压后的实 ...
- java你可能不知道的事(2)--堆和栈
在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...
- error=Error Domain=NSURLErrorDomain Code=-1003
我的情况:模拟器 可以返回数据 .真机不可以.我手机连接的同事的共享,我以为他的网段和后台的网段在同一个网段.一直在找错误,打开手机网络设置一看 ,原来不在同一网段.手机的网络必须要跟PC的在同一个 ...