HDU_1401——分步双向BFS,八进制位运算压缩,map存放hash
There are four identical pieces on the board. In one move it is allowed to:
> move a piece to an empty neighboring field (up, down, left or right),
> jump over one neighboring piece to an empty field (up, down, left or right). There are 4 moves allowed for each piece in the configuration shown above. As an example let's consider a piece placed in the row 4, column 4. It can be moved one row up, two rows down, one column left or two columns right.
Write a program that:
> reads two chessboard configurations from the standard input,
> verifies whether the second one is reachable from the first one in at most 8 moves,
> writes the result to the standard output.
2 4 3 3 3 6 4 6
#include <cstdio>
#include <map>
#include <queue>
#include <algorithm>
using namespace std; struct point
{
int x,y;
bool check()
{
if(x>= && x<= && y>= && y<=)
{
return true;
}
return false;
}
};
struct chess
{
point pos[];
int step;
bool check(int j)
{
for(int i=;i<;i++)
{
if(i!=j && pos[j].x==pos[i].x && pos[j].y==pos[i].y)
return true;
}
return false;
}
}start,end; const int dir[][]={,,,-,,,-,};
map<int,int>mapint;
map<int,int>::iterator it; /*
对棋盘状态进行进制压缩处理,棋子坐标(x,y):0~7
变成二进制:000~111,一共有4个棋子,所以一共有(x,y)坐标4个
把棋型压缩成二进制形式,共24位。因为棋子都是相同的
所以每次压缩前,都要对棋子坐标(x,y)进行排序,
否则棋型相同棋子序号不同时,会出现不同的压缩状态
*/
bool cmp(point a,point b) //按x升序排序,如果x相等就按y升序排序
{
return a.x!=b.x ? a.x<b.x : a.y<b.y; //>降序,<升序
}
int get_hash(point *temp)
{
int res = ;
sort(temp,temp+,cmp);
for(int i=;i<;i++) //枚举棋子
{
res |= ( temp[i].x<<(*i) );
res |= ( temp[i].y<<(*i+) );
}
return res;
} bool BFS(int flag,chess temp) //flag=1:从起点开始搜索,flag=2:终点开始
{
/*
if(flag == 2) //当从终点开始搜索时,先在存储起点搜索压缩状态的map容器中查找,是否已经到到达过终点
{
it = mapint.find(get_hash(temp.pos));
if(it != mapint.end())
{
return true;
}
}
mapint[get_hash(temp.pos)] = flag;
*/
queue<chess>que;
que.push(temp); while(!que.empty())
{
temp = que.front();
que.pop();
if(temp.step >= ) //搜索步数不超过4步
{
continue;
}
for(int i=;i<;i++) //枚举方向
{
for(int j=;j<;j++) //枚举棋子
{
chess next = temp;
next.step++;
next.pos[j].x += dir[i][];
next.pos[j].y += dir[i][]; if(!next.pos[j].check()) //判断棋子是否在棋盘内
{
continue;
}
if(next.check(j)) //判断棋子j是否和其他棋子重叠
{
next.pos[j].x += dir[i][]; //重叠之后再前进一步
next.pos[j].y += dir[i][];
if(!next.pos[j].check()) //再次检查是否越界
{
continue;
}
if(next.check(j)) //再次检查是否重叠
{
continue;
}
} int hash = get_hash(next.pos); //获得一种新的状态
it = mapint.find(hash); //在容器中搜索这个新状态 if(flag == ) //从起点开始的搜索
{ if(it == mapint.end()) //没找到,记录压缩状态,推入队列
{
mapint[hash] = flag;
que.push(next);
} else if(it -> second == ) //找到的是终点搜索过来的状态
{
return true;
} }
else //从终点开始的搜索
{
if(it == mapint.end()) //没找到,推入队列
{
que.push(next); //不需要再生成压缩状态并记录了
}
else if(it -> second == ) //找到的是起点搜索过来的状态
{
return true;
}
}
}
}
}
return false;
} int main()
{
while(~scanf("%d%d",&start.pos[].x,&start.pos[].y))
{
for(int i=;i<;i++)
{
scanf("%d%d",&start.pos[i].x,&start.pos[i].y);
}
for(int i=;i<;i++)
{
scanf("%d%d",&end.pos[i].x,&end.pos[i].y);
}
for(int i=;i<;i++) //把棋盘坐标由1~8转化成0~7,方便进制压缩
{
start.pos[i].x--; start.pos[i].y--;
end.pos[i].x--; end.pos[i].y--;
}
start.step = end.step = ; mapint[get_hash(start.pos)] = ; //搜索之前先把初始压缩状态放入map容器,防止起点和终点一样的情况
mapint[get_hash(end.pos)] = ; if(BFS(,start) || BFS(,end))
{
printf("YES\n");
}
else
{
printf("NO\n");
} mapint.clear(); //狗日的一定要记住,容器什么的每次要清空
}
return ;
}
HDU_1401——分步双向BFS,八进制位运算压缩,map存放hash的更多相关文章
- HDU_1401——同步双向BFS,八进制位运算压缩,map存放hash
这个速度比分步快一点,内存占的稍微多一点 Problem Description Solitaire is a game played on a chessboard 8x8. The rows an ...
- HDU_1401——分步双向BFS,八进制乘权值压缩,map存放hash
Problem Description Solitaire is a game played on a chessboard 8x8. The rows and columns of the ches ...
- HDU 3605 Escape (网络流,最大流,位运算压缩)
HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...
- uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)
这题数据大容易TLE 优化:预处理, 可以先枚举出5^3的状态然后判断合不合法,但是由于题目说了有很多墙壁,实际上没有那么多要转移的状态那么可以把底图抽出来,然后3个ghost在上面跑到时候就不必判断 ...
- poj2965(位运算压缩+bfs+记忆路径)
题意:有个4*4的开关,里面有着16个小开关 -+-- ---- ---- '+'表示开关是关着的,'-'表示开关是开着的,只有所有的开关全被打开,总开关才会被打开.现在有一种操作,只要改变某个开关, ...
- poj1753(位运算压缩状态+bfs)
题意:有个4*4的棋盘,上面摆着黑棋和白旗,b代表黑棋,w代表白棋,现在有一种操作,如果你想要改变某一个棋子的颜色,那么它周围(前后左右)棋子的颜色都会被改变(白变成黑,黑变成白),问你将所有棋子变成 ...
- 【BFS】【位运算】解药还是毒药
[codevs2594]解药还是毒药 Description Smart研制出对付各种症状的解药,可是他一个不小心,每种药都小小地配错了一点原料,所以这些药都有可能在治愈某些病症的同时又使人患上某些别 ...
- HDU5627--Clarke and MST (bfs+位运算)
http://www.cnblogs.com/wenruo/p/5188495.html Clarke and MST Time Limit: 2000/1000 MS (Java/Others) M ...
- POJ 1753 bfs+位运算
T_T ++运算符和+1不一样.(i+1)%4 忘带小括号了.bfs函数是bool 型,忘记返回false时的情况了.噢....debug快哭了...... DESCRIPTION:求最少的步骤.使得 ...
随机推荐
- C#泛型类的简单创建与使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- bootstrap新闻模块样式模板
<!-- news beginning --> <div class="container mp30"> <div class="row&q ...
- 条件注释判断浏览器版本<!--[if lt IE 9]>(转载)
<!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]--> <!--[if IE]> 所有的IE可识别 <![ ...
- HTML5 Canvas 概述
本文中,我们将探索如何使用HTML5的Canvas API.Canvas API很酷,我们可以通过它来动态创建生成和展示图形,图表,图像以及动画.本文将使用渲染API(rendering API)的基 ...
- protocol buffer使用简介
之前在工作中用到了protocol buffer(此处简称PB)(主要对数据进行序列化与反序列化,方便网络传输中的编解码),之后发现这是一个好东西,在此稍微记录下该工具如何使用,方便以后查阅 官网地址 ...
- jvm-初探
目录 1,Java体系结构 2.jvm执行引擎 3,ClassLoader的体系结构 4,java class文件 概述 其实,学java不算新手了,但是却感觉很多基本的知识,我们一开始也许是记住而不 ...
- 使用第三方SDK出现: duplicate symbol _llvm.cmdline in:
如果是同一个静态库中的文件链接的时候有冲突,可能是这个静态库不支持模拟器,真机运行就好了. 或者可以使用xcode7的虚拟机跑也是没问题的. duplicate symbol _llvm.cmdlin ...
- apache-maven-3.3.9集成apache-tomcat-7.0.72实现热部署配置细节
1.开发环境.Maven.Tomcat安装不作描述,搜索引擎很多文章可供参考. 2.Tomcat配置文件修改 1)Tomcat管理权限配置 1.1)在tomcat安装目录下找到tomcat-users ...
- Smarty中{literal}的使用详解
{literal} <script>function Login(){ document.LoginForm.submit();}</script>{/literal} == ...
- 让 zend studio 识别 Phalcon语法并且进行语法提示
让 zend studio 识别 Phalcon语法并且进行语法提示 https://github.com/phalcon/phalcon-devtools/tree/master/ide 下载解压 ...