hdu1067
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define MAXN 1000007
typedef long long ll;
ll Hash[MAXN];
struct Node{
int map[4][8],step;
bool operator == (const Node &p) const {
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)
if(map[i][j]!=p.map[i][j])
return false;
return true;
}
//手写hash
ll HashValue(){
ll value=0;
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)
value+=(value<<ll(1))+(ll)map[i][j];
return value;
}
};
Node Start,End;
void Initaite(){
memset(Hash,-1,sizeof(Hash));
for(int i=0;i<4;i++){
Start.map[i][0]=0;
for(int j=1;j<8;j++){
scanf("%d",&Start.map[i][j]);
}
}
Start.step=0;
}
//最后的结果
void GetEnd(){
for(int i=0;i<4;i++){
End.map[i][7]=0;
for(int j=0;j<7;j++){
End.map[i][j]=(i+1)*10+(j+1);
}
}
}
//取得value的hash值+hash判重
bool HashInsert(ll value){
int v=value%MAXN;
while(Hash[v]!=-1&&Hash[v]!=value){
v+=10;
v%=MAXN;
}
if(Hash[v]==-1){
Hash[v]=value;
return true;
}
return false;
}
void bfs(){
queue<Node>Q;
Node p,q;
Q.push(Start);
HashInsert(Start.HashValue());
while(!Q.empty()){
p=Q.front();
Q.pop();
for(int i=0;i<4;i++){
for(int j=0;j<8;j++){
if(!p.map[i][j]){
q=p;
q.step++;
int value=p.map[i][j-1]+1;//找比map[i][j-1]大1的数
if(value==1||value%10==8)continue;//0或者value为7的不能移动
int x,y,flag=true;
for(int k=0;k<4&&flag;k++){
for(int l=1;l<8&&flag;l++){
if(p.map[k][l]==value){
x=k,y=l;
flag=false;
}
}
}
if(!flag){
swap(q.map[i][j],q.map[x][y]);
ll value=q.HashValue();
//hash判重
if(HashInsert(value)){
if(q==End){
printf("%d\n",q.step);
return ;
}
Q.push(q);
}
}
}
}
}
}
puts("-1");
}
void Solve(){
int k=0;
//将11,21,31,41这四个数移到第0列
for(int i=0;i<4;i++){
for(int j=1;j<8;j++){
if(Start.map[i][j]==(k+1)*10+1){
swap(Start.map[i][j],Start.map[k][0]);
k++,i=0,j=0;
}
}
}
if(Start==End){
puts("0");//前四步不记录总步数
return ;
}
bfs();
}
int main(){
int _case;
scanf("%d",&_case);
GetEnd();
while(_case--){
Initaite();
Solve();
}
return 0;
}
hdu1067的更多相关文章
- hdu-1067(最大独立集)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1068 题意:一个男生集合和一个女生集合,给出两个集合之间一一对应的关系,求出两个集合中最大独立集的点数 ...
- HDU1067 Gap
题目: Let's play a card game called Gap. You have 28 cards labeled with two-digit numbers. The first d ...
- hdu&&poj搜索题题号
搜索 hdu1067 哈希 hdu1401 双向搜索 hdu1430 哈希 hdu1667 跌搜+启发式函数 hdu1685 启发式搜索 hdu1813 启发式搜索 hdu1885 状态压缩搜索 hd ...
随机推荐
- Docker 镜像篇
镜像是 Docker 容器的基石,容器是镜像的运行实例,有了镜像才能启动容器. docker两个跟镜像有关的命令: hello-world - 最小的镜像 hello-world 是 Docker 官 ...
- python第三篇:python、flask关系映射
python中关系映射主要包括三种:一对多关系映射.一对一关系映射.多对多关系映射. 一对多关系映射 一方:Student(学生) 添加关联属性和反向引用 多方:Article(文章) 添加外键关联 ...
- 一個在WCF學習中的小教訓(本人非科班菜鳥,此經驗無參考價值,衹是自己的經驗記錄)
1.关于“ServiceHost 仅支持类服务类型”的解决: Service属性必须执行,不是接口. 改为下图所示: 解决! (注:按朱哥的方法WCF已经可以通信---截至今天的11:11(例子在 ...
- linux 替换目录下文件所有关键字
for i in *;do sed -ie 's/_test2/_test3/g' $i; sed -ie 's/_type2/_type3/g' $i; done 539down voteaccep ...
- 【二叉查找树】03验证是否为二叉查找树【Validate Binary Search Tree】
本质上是递归遍历左右后在与根节点做判断,本质上是后序遍历 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...
- VC用MCI播放mp3等音乐文件
VC播放mp3等音乐文件,可以使用MCI.MCI ( Media Control Interface ) ,即媒体控制接口,向基于Windows操作系统的应用程序提供了高层次的控制媒体设备接口的能力. ...
- ONVIF协议测试工具 ONVIF Device Test Tool 29 12.12 最新版
ONVIF协议测试工具 ONVIF Device Test Tool 29 12.12 最新版 包含文档和工具,本人亲测,好用! http://download.csdn.net/detail/li_ ...
- SPOJ705 Distinct Substrings (后缀自动机&后缀数组)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- NOIp2018集训test-10-17 (bike day3)
发现自己gradully get moodier and moodier了 负面情绪爆发地越来越频繁,根本out of control,莫名其妙地就像着了魔一样 为什么用英语大概是因为今天早上早自习因 ...
- 麻省理工《C内存管理和C++面向对象编程》笔记---第一讲:认识C和内存管理
最近一年都在用.net和Java,现在需要用C了.昨天看到博客园首页的麻省理工开放课程,就找来看看,正好复习一下.这门<C内存管理和C++面向对象编程>不是那种上来就变量,循环的千篇一律的 ...