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 ...
随机推荐
- 翻译Lanlet2
Here is more information on the basic primitives that make up a Lanelet2 map. Read here for a primer ...
- Java_异常_05_ OutOfMemoryError: Java heap space
一.异常现象: 二.异常原因 JAVA的堆栈设置太小 注: 出现此异常之后,会引发其他的问题. 三.异常解决 手动设置Heap size: 修改 TOMCAT_HOME/bin/catalina.sh ...
- Java微信开发_03_使用测试号进行开发
今天进行自定义菜单的开发时,发现公众号没有自定义菜单的权限.于是想到用测试号,但微信服务器如何区分你要请求的是公众号还是测试号呢. 我们可以发现不同公众号的appID和appsecre是不同的,一对a ...
- mybatis学习第(一)天
课程安排: Mybatis和springMVC通过订单商品案例驱动 第一天:基础知识(重点,内容量多) 对原生态jdbc程序(单独使用jdbc开发)问题总结 Mybatis框架原理 Mybatis的入 ...
- 计算机丨浏览器访问出现DNS_PROBE_POSSIBLE解决方法
方法1.打开命令控制台输入: netsh winsock reset.提示重启,电脑重启后就ok了. 其他方法待续......
- leetcode 3 Longest Substring Without Repeating Characters(滑动窗口)
用滑动窗口的思想来做.用一个unordered_map来查询之前的char有没有在现在的窗口中. class Solution { public: int lengthOfLongestSubstri ...
- Struts2 - 配置文件详解
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "- ...
- 【二叉树的递归】02二叉树的最大深度【Maximum Depth of Binary Tree】
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,找出他的最小的深度 ...
- NOI2018网络同步赛游记
Day1 t1是一道NOI选手眼中的送分题,对于我来说还是有难度的,用了个把小时想了出来可持久化并查集的做法,最后一个点被卡常.赛后才发现Kruskal重构树是这样的简单.t2.t3由于我真的是太弱了 ...
- 汇编题目:在DOS下,按F1键后改变当前屏幕的显示颜色
我们都知道int9中断是键盘的按键中断程序,按下键盘触发int9中断,不懂int9中断的请自己去百度查查说明和用法 利用中断任务安装一个新的int 9中断例程,功能:在DOS下,按F1键后改变当前屏幕 ...