Problem Description
Solitaire is a game played on a chessboard 8x8. The rows and columns of the chessboard are numbered from 1 to 8, from the top to the bottom and from left to right respectively.
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.
 
Input
Each of two input lines contains 8 integers a1, a2, ..., a8 separated by single spaces and describes one configuration of pieces on the chessboard. Integers a2j-1 and a2j (1 <= j <= 4) describe the position of one piece - the row number and the column number respectively. Process to the end of file.
 
Output
The output should contain one word for each test case - YES if a configuration described in the second input line is reachable from the configuration described in the first input line in at most 8 moves, or one word NO otherwise.
 
Sample Input
4 4 4 5 5 4 6 5
2 4 3 3 3 6 4 6
 
Sample Output
YES
 
 #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的更多相关文章

  1. HDU_1401——同步双向BFS,八进制位运算压缩,map存放hash

    这个速度比分步快一点,内存占的稍微多一点 Problem Description Solitaire is a game played on a chessboard 8x8. The rows an ...

  2. HDU_1401——分步双向BFS,八进制乘权值压缩,map存放hash

    Problem Description Solitaire is a game played on a chessboard 8x8. The rows and columns of the ches ...

  3. HDU 3605 Escape (网络流,最大流,位运算压缩)

    HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...

  4. uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)

    这题数据大容易TLE 优化:预处理, 可以先枚举出5^3的状态然后判断合不合法,但是由于题目说了有很多墙壁,实际上没有那么多要转移的状态那么可以把底图抽出来,然后3个ghost在上面跑到时候就不必判断 ...

  5. poj2965(位运算压缩+bfs+记忆路径)

    题意:有个4*4的开关,里面有着16个小开关 -+-- ---- ---- '+'表示开关是关着的,'-'表示开关是开着的,只有所有的开关全被打开,总开关才会被打开.现在有一种操作,只要改变某个开关, ...

  6. poj1753(位运算压缩状态+bfs)

    题意:有个4*4的棋盘,上面摆着黑棋和白旗,b代表黑棋,w代表白棋,现在有一种操作,如果你想要改变某一个棋子的颜色,那么它周围(前后左右)棋子的颜色都会被改变(白变成黑,黑变成白),问你将所有棋子变成 ...

  7. 【BFS】【位运算】解药还是毒药

    [codevs2594]解药还是毒药 Description Smart研制出对付各种症状的解药,可是他一个不小心,每种药都小小地配错了一点原料,所以这些药都有可能在治愈某些病症的同时又使人患上某些别 ...

  8. HDU5627--Clarke and MST (bfs+位运算)

    http://www.cnblogs.com/wenruo/p/5188495.html Clarke and MST Time Limit: 2000/1000 MS (Java/Others) M ...

  9. POJ 1753 bfs+位运算

    T_T ++运算符和+1不一样.(i+1)%4 忘带小括号了.bfs函数是bool 型,忘记返回false时的情况了.噢....debug快哭了...... DESCRIPTION:求最少的步骤.使得 ...

随机推荐

  1. [转] [翻译]图解boost::bind

    http://kelvinh.github.io/blog/2013/12/03/boost-bind-illustrated/ 其实这是很久之前留的一个坑了,一直没有填.. 记得在刚开始看到 boo ...

  2. [转] restrict关键字用法

    PS: 在函数中,指针参数指定了restrict,表示这个指针指向的这段区域只能通过这个指针修改 c99中新增加了一个类型定义,就是restrict. 看了下网上的相关贴子,但还是问题解决的不够.下面 ...

  3. Python之路,Day15 - Django适当进阶篇

    Python之路,Day15 - Django适当进阶篇   本节内容 学员管理系统练习 Django ORM操作进阶 用户认证 Django练习小项目:学员管理系统设计开发 带着项目需求学习是最有趣 ...

  4. gulp初涉

    1.什么是gulp? gulp是前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器:它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成:使用它,不仅可以很 ...

  5. mysql查看binlog日志

    1.语法:(用于在二进制日志中显示事件.如果您不指定’log_name’,则显示第一个二进制日志.LIMIT子句和SELECT语句具有相同的语法.) show binlog events [IN 'l ...

  6. MySQL无法登录服务器解决方法

    提示:#2000 无法登录 MySQL 服务器 今天用本机装了个phpMyAdmin,版本3.4.8,想用它来连一台内网服务器上的Mysql,于是乎修改phpMyAdmin配置文件config.inc ...

  7. ios开发常见问题及解决办法

    1 . storyboard连线问题 产生原因:将与storyboard关联的属性删除了,但是storyboard中还保持之前所关联的属性. 解决: 点击view controller    点击这排 ...

  8. Rechability的简单使用

    AppDelegate.m #import "AppDelegate.h" #import "Reachability.h" @interface AppDel ...

  9. Asp.net IsPostBack

    Page.IsPostBack是一个标志:当前请求是否第一次打开.调用方法为:Page.IsPostBack或者IsPostBack或者this.IsPostBack或者this.Page.IsPos ...

  10. 新手对css的浅识

    对于css的一个初步理解与认识 在最近的学习中接触到了之前自己从来都不曾想过的语言,C语言,html超文本标记语言等等,还有今天在这里我要进行分析的css,之前浏览过很多的网页,也曾想过这里面的秘密, ...