【CS 1004】四子连棋(bfs+hash,良心带样例解释)
来源:互联网 发布:app直播源码下载 编辑:程序博客网 时间:2024/05/17 09:04
这篇附带题目的样例说明哦233333
良心【雾】
大杀四方
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● ○ ●
○ ● ○ ●
● ○ ● ○
○ ● ○
|●|○|●| |
|○|●|○|●|
|●|○|●|○|
|○|●|○| |【博主美化失败图。。。(:з」∠)_】
输入描述 Input Description
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出描述 Output Description
用最少的步数移动到目标棋局的步数。
样例输入 Sample Input
BWBO
WBWB
BWBW
WBWO
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
hi
233先解释样例下:
将2,4处黑子上移到1,4处,将2,3处白子右移到2,4,再将2,2处黑子移到2,3处。3子完成;
将4,3处白子右移到4,4处,再将4,2处黑子右移到4,3处,完成四子连棋
思路:
对于这个bfs广搜的问题我们要考虑到这几点:
首先要将符合题意的条件都表示出来,就是指“四子连棋”的情况,即done函数和check函数,分析每行每列包括两条对角线上能不能四子连棋;
其次用哈希值来处理图上各点,将O、B、W分别用0、1、2来代替,在hash函数中相当于完成三进制转换;
继而本题规定双方可任意先走棋子,因此要考虑到如何才能将两方轮流设置走(样例中我貌似是黑白先走都走出来答案为5步),因此才在bfs一开头设置了“q.push(s);s.next=2;q.push(s); ”
然后弄上一个好的bfs套上再细调一下细节就能处理过去
代码如下:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>using namespace std;const int mod=1e5+3;const int dx[]={0,1,0,-1};const int dy[]={1,0,-1,0};struct emm{ int ma[5][5]; int step,next;}s,f;int ans;queue<emm>q;bool ha[mod<<1];inline bool check(int x1,int x2,int x3,int x4){ if(x1==x2&&x2==x3&&x3==x4&&x4==x1) return 1; return 0;}inline bool done(){ for(int i=1;i<=4;i++) { if(check(f.ma[i][1],f.ma[i][2],f.ma[i][3],f.ma[i][4])) return 1; if(check(f.ma[1][i],f.ma[2][i],f.ma[3][i],f.ma[4][i])) return 1; } if(check(f.ma[1][1],f.ma[2][2],f.ma[3][3],f.ma[4][4])) return 1; if(check(f.ma[1][4],f.ma[2][3],f.ma[3][2],f.ma[4][1])) return 1; return 0;}inline int hash(emm z){ int ret=0,key=1; for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) { ret+=z.ma[i][j]*key; key*=3; } ret%=mod; return ret;}inline bool can(int x,int y){ int nxt=f.next; if(x<=0||x>4||y<=0||y>4) return 0; if(f.ma[x][y]==nxt) return 1; return 0;}void move(int x,int y){ for(int i=0;i<4;i++) { int zx=x+dx[i],zy=y+dy[i]; if(can(zx,zy)) { emm t=f; swap(t.ma[x][y],t.ma[zx][zy]); if(!ha[hash(t)]) { t.step=f.step+1; if(f.next==1) t.next=2; if(f.next==2) t.next=1; q.push(t); } } }}void bfs(){ q.push(s); s.next=2; q.push(s); while(!q.empty()) { f=q.front(); if(done()) { ans=f.step; return; } ha[hash(f)]=1; q.pop(); for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) if(!f.ma[i][j]) move(i,j); }}char ch;int main(){ memset(ha,0,sizeof(ha)); for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) { cin>>ch; if(ch=='B') s.ma[i][j]=1; else if(ch=='W') s.ma[i][j]=2; else if(ch=='O') s.ma[i][j]=0; } s.step=0; s.next=1; bfs(); if(!ans) ans=1; printf("%d",ans); return 0;}
- 【CS 1004】四子连棋(bfs+hash,良心带样例解释)
- hdu 1067 BFS + hash
- hdu 1067(hash+bfs)
- hdu1067 Gap (bfs+hash)
- 八面码问题(BFS+Hash)
- hdoj1067 Gap(bfs+hash)
- 八数码 BFS+HASH
- CS 400 BFS-DFS 构造
- Hash 的解释说明
- 中文解释SqlHelper.cs类
- 【CS 1376】帕秋莉•诺蕾姬(Hash)
- POJ-3697(hash+bfs)
- 【BFS+hash】The Social Network
- POJ 2946 字符串hash + BFS
- 704 - Colour Hash(双向bfs)
- hdu 1067 Gap bfs+hash
- hdu 1067 Gap bfs+hash
- HDU 1067(HASH + BFS)
- 【国际】加拿大声明代币可能属于证券并公布辨别方法
- 数据结构-线性表-单链表
- poj 1000 a+b problem
- JS实现上传图片实时预览
- Linux下find命令使用
- 【CS 1004】四子连棋(bfs+hash,良心带样例解释)
- node启动_安装_依赖_构建
- javaWeb开发过程中遇到的乱码问题
- 方法重写的一大两小两同
- 高偏差、高方差、低精确率与低召回率、混淆矩阵
- Java实现二分查找
- js实现页面弹框效果
- Android View-measure
- caffe训练模型并预测图片类型