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 ...
随机推荐
- HDU2544最短路模板,
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<algorithm> ...
- 什么是shell【TLCL】
常用命令 date cal df——report file system disk space usage free——display amount of free and used memory i ...
- RSA加密方法java工具类
package com.qianmi.weidian.common.util; import java.io.ByteArrayOutputStream; import java.security.K ...
- eclipse从Git获取项目更新
1.项目上右键 ——> Team ——> pull 如果报错: 解决方法: 依次打开:Window ——> Preferences ——> Team ——> ...
- 第一篇:Git操作详解
最近由于项目的需要,我需要负责整个项目的托管,其中涉及到很多Git相关的命令,所以就将之前用到的git相关的命令做了一个总结和归纳.由于开发环境是Linux,所以我接下来的操作命令均针对Linux环境 ...
- 【Selenium】Option加载用户配置,Chrom命令行参数
about:version - 显示当前版本 about:memory - 显示本机浏览器内存使用状况 about:plugins - 显示已安装插件 about:histograms - 显示历史记 ...
- $.ajax()方法详解(转)
以下内容转自:http://www.cnblogs.com/tylerdonet/p/3520862.html 尊重原创,请访问原创文章 jquery中的ajax方法参数总是记不住,这里记录一下. ...
- Python中进度条如何实现
print源码,参数end默认值为换行符,需要置成空,就会实现打印一行的效果 import time for i in range(100): time.sleep(1)#sleep一秒再输出 # 需 ...
- CQOI2018做题记录
T1.破解D-H协议 传送门 这个题就是BSGS的板子题-- 然后这里补充一点嘛,就是第二重循环的枚举范围.我们是在枚举\(a^{tm-y}\),把tm换成i,这个的最大值就是\(i - (m - 1 ...
- Linux如何打开执行脚本
命令行下例如要打开startmysql.sh就直接 sh /目录/目录当前界面下就简单了在这个SH文件目录下打开终端 输入 sh startmysql.sh 回车或者对这个文件右键 打开 选择“在终端 ...