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 ...
随机推荐
- Android关闭USB的ADB调试和文件传输功能(禁用USB)【转】
本文转载自:https://blog.csdn.net/jun4331247/article/details/51201825 通过设置系统属性(System Property)[persist.sy ...
- java入门了解07
1.集合: 1.1相比数组的优势: a.可以存储任意类型的对象数据,数组只能存储一种类型的变量 b.集合的长度会发生变化,数组不会 1.2集合概述 ----|Collection: 单列集合 ---- ...
- ThinkPHP 小技巧
中文截取函数 函数解释: msubstr($str, $start=0, $length, $charset=”utf-8″, $suffix=true) $str:要截取的字符串 $start=0: ...
- castle windsor学习----ComponentModel construction contributors
public class RequireLoggerProperties : IContributeComponentModelConstruction { public void ProcessMo ...
- linux用户管理与用户组的重要文件
用户管理的2个重要文件:/etc/passwd和/etc/shadow. /etc/passwd文件里存放的是用户的信息,其中不包含密码:passwd文件中每一行代表一个用户,且每一行分为7个字段使用 ...
- ava:Map借口及其子类HashMap三
ava:Map借口及其子类HashMap三 HashMap常用子类(异步非安全线程,性能高: Hashtable:同步的安全线程,性能低) map(HashMap)中的key,value可以通过 Se ...
- 序列化工具类({对实体Bean进行序列化操作.},{将字节数组反序列化为实体Bean.})
package com.dsj.gdbd.utils.serialize; import java.io.ByteArrayInputStream; import java.io.ByteArrayO ...
- node.js redis对事务的控制
redis对事务的支持还是比较差的,就是把所有的执行命令方到队列中一个一个执行 multi开启一个事务,exec执行事务集合中的命令 代码: var redisClient; redisClient. ...
- Appium-关于appium的原生控件的 xpath 定位问题及常用方法
最近遇到的项目,发现很多元素,都没有标明id.text.content-desc,classname中又有很多是相同,导致无法定位 第一,appium1.5及之后的版本废弃了name属性(如name= ...
- Oracle忘记用户名密码
一.oracle 11g登录服务开启 成功安装Oracle 11g后,共有7个服务,这七个服务的含义分别为:1. Oracle ORCL VSS Writer Service:Oracle卷映射拷贝写 ...