POJ-3131-Cubic Eight-Puzzle(双向BFS+哈希)
Description
Let’s play a puzzle using eight cubes placed on a 3 × 3 board leaving one empty square.
Faces of cubes are painted with three colors. As a puzzle step, you can roll one of the cubes to a adjacent empty square. Your goal is to make the specified color pattern visible from above by a number of such steps.
The rules of this puzzle are as follows.
Coloring of Cubes: All the cubes area colored in the same way as shown in Figure 1. The opposite faces have the same color.
Figure 1: Coloring of a cube
Initial Board State: Eight cubes are placed on the 3 × 3 board leaving one empty square. All the cubes have the same orientation as shown in Figure 2. As shown in the figure, squares on the board are given x and y coordinates,
(1, 1), (1, 2), …, and (3, 3). The position of the initially empty square may vary.Figure 2: Initial board state
Rolling Cubes: At each step, we can choose one of the cubes adjacent to the empty square and roll it into the empty square, leaving the original position empty. Figure 3 shows an example.
Figure 3: Rolling a cube
Goal: The goal of this puzzle is to arrange the cubes so that their top faces form the specified color pattern by a number of cube rolling steps described above.
Your task is to write a program that finds the minimum number of steps required to make the specified color pattern from the given initial state.
Input
The input is a sequence of datasets. The end of the input is indicated by a line containing two zeros separated by a space. The number of datasets is less than 16. Each dataset is formatted as follows.
x y F11 F21 F31 F12 F22 F32 F13 F23 F33
The first line contains two integers x and y separated by a space, indicating the position (x, y) of the initially empty square. The values of x and y are 1, 2, or 3.
The following three lines specify the color pattern to make. Each line contains three characters F1j, F2j, and F3j, separated by a space. Character Fij indicates
the top color of the cube, if any, at the position (i, j) as follows:
B:
Blue,
W:
White,
R:
Red,
E:
the square is Empty.
There is exactly one ‘E
’ character in each dataset.
Output
For each dataset, output the minimum number of steps to achieve the goal, when the goal can be reached within 30 steps. Otherwise, output “-1
” for the dataset.
Sample Input
1 2
W W W
E W W
W W W
2 1
R B W
R W W
E W W
3 3
W B W
B R E
R B R
3 3
B W R
B W R
B E R
2 1
B B B
B R B
B R E
1 1
R R R
W W W
R R E
2 1
R R R
B W B
R R E
3 2
R R R
W E W
R R R
0 0
Sample Output
0
3
13
23
29
30
-1
-1
Source
思路:数据太大,先抽象出状态,再哈希一下,然后就是双向BFS。
#include <stdio.h>
#include <string.h>
#include <stack>
using namespace std;
#define INF 99999999
struct{
int step,state;
}t,que1[1000000],que2[1000000];
stack<int>stk;
bool vis1[5000007],vis2[5000007];
int top1,top2,bottom1,bottom2,mp[9],nxt[2][7]={{0,4,6,5,1,3,2},{0,5,3,2,6,1,4}},head[5000007],next[5000007],val[5000007],total;
int hashval(int x)
{
int t,i;
t=x%5000007;
for(i=head[t];i!=-1;i=next[i])
{
if(val[i]==x) return i;
}
val[total]=x;
next[total]=head[t];
head[t]=total;
total++;
return total-1;
}
void pushtarget(int cnt,int state)
{
if(cnt==-1)
{
vis2[hashval(state)]=1;
que2[bottom2].step=0;
que2[bottom2].state=state;
bottom2++;
return;
}
if(mp[cnt]%2)
{
pushtarget(cnt-1,state*7+mp[cnt]);
pushtarget(cnt-1,state*7+mp[cnt]+1);
}
else pushtarget(cnt-1,state*7);
}
int getstate()
{
int temp=0;
for(int i=8;i>=0;i--)
{
temp=temp*7+mp[i];
}
return temp;
}
void spread(int x)
{
int i=0,temp,cnt,old;
while(i<9)
{
if(x%7==0) cnt=i;
mp[i++]=x%7;
x/=7;
}
cnt+=1;
if(cnt>=0 && cnt<9 && cnt%3>0)
{
old=mp[cnt];
mp[cnt-1]=nxt[0][mp[cnt]];
mp[cnt]=0;
stk.push(getstate());
mp[cnt]=old;
mp[cnt-1]=0;
}
cnt-=1;
cnt-=1;
if(cnt>=0 && cnt<9 && cnt%3<2)
{
old=mp[cnt];
mp[cnt+1]=nxt[0][mp[cnt]];
mp[cnt]=0;
stk.push(getstate());
mp[cnt]=old;
mp[cnt+1]=0;
}
cnt+=1;
cnt-=3;
if(cnt>=0 && cnt<9)
{
old=mp[cnt];
mp[cnt+3]=nxt[1][mp[cnt]];
mp[cnt]=0;
stk.push(getstate());
mp[cnt]=old;
mp[cnt+3]=0;
}
cnt+=3;
cnt+=3;
if(cnt>=0 && cnt<9)
{
old=mp[cnt];
mp[cnt-3]=nxt[1][mp[cnt]];
mp[cnt]=0;
stk.push(getstate());
mp[cnt]=old;
mp[cnt-3]=0;
}
cnt-=3;
}
int bfs()
{
int step1=0,step2=0,ans=INF,temp;
for(step1=0;step1<=20;step1++)
{
while(top1<bottom1 && que1[top1].step==step1)
{
spread(que1[top1].state);
while(!stk.empty())
{
temp=stk.top();
stk.pop();
if(vis2[hashval(temp)])
{
return step1+step2+1;
}
if(!vis1[hashval(temp)])
{
vis1[hashval(temp)]=1;
que1[bottom1].state=temp;
que1[bottom1].step=que1[top1].step+1;
bottom1++;
}
}
top1++;
}
while(top2<bottom2 && que2[top2].step==step2 && step2<9)
{
spread(que2[top2].state);
while(!stk.empty())
{
temp=stk.top();
stk.pop();
if(vis1[hashval(temp)]) return step1+step2+2;
if(!vis2[hashval(temp)])
{
vis2[hashval(temp)]=1;
que2[bottom2].state=temp;
que2[bottom2].step=step2+1;
bottom2++;
}
}
top2++;
}
if(step2<9) step2++;
}
return -1;
}
int main()
{
int x,y,i,j,temp;
char ctemp;
while(~scanf("%d%d",&y,&x) && x)
{
x--;
y--;
top1=top2=bottom1=bottom2=0;
memset(vis1,0,sizeof vis1);
memset(vis2,0,sizeof vis2);
memset(head,-1,sizeof head);
total=0;
while(!stk.empty()) stk.pop();
for(i=0;i<9;i++)
{
ctemp=getchar();
if(ctemp=='\n' || ctemp==' ')
{
i--;
continue;
}
if(ctemp=='W')mp[i]=1;
else if(ctemp=='B') mp[i]=3;
else if(ctemp=='R') mp[i]=5;
else if(ctemp=='E') mp[i]=0;
}
pushtarget(8,0);
temp=0;
for(i=8;i>=0;i--)
{
if(i!=x*3+y) temp=temp*7+1;
else temp*=7;
}
if(vis2[hashval(temp)])
{
printf("0\n");
continue;
}
vis1[hashval(temp)]=1;
que1[bottom1].step=0;
que1[bottom1].state=temp;
bottom1++;
printf("%d\n",bfs());
}
}
POJ-3131-Cubic Eight-Puzzle(双向BFS+哈希)的更多相关文章
- UVA-1604 Cubic Eight-Puzzle (双向BFS+状态压缩+限制搜索层数)
题目大意:立体的八数码问题,一次操作是滚动一次方块,问从初始状态到目标状态的最少滚动次数. 题目分析:这道题已知初始状态和目标状态,且又状态数目庞大,适宜用双向BFS.每个小方块有6种状态,整个大方格 ...
- poj 3131 Cubic Eight-Puzzle 双向广搜 Hash判重
挺不错的题目,很锻炼代码能力和调试能力~ 题意:初始格子状态固定,给你移动后格子的状态,问最少需要多少步能到达,如果步数大于30,输出-1. 由于单向搜索状态太多,搜到二十几就会爆了,所以应该想到双向 ...
- POJ 1915 经典马步 双向bfs
拿这个经典题目开刀...........可是双向时间优势在这题上的效果不太明显 #include <iostream> #include <algorithm> #includ ...
- Eight (HDU - 1043|POJ - 1077)(A* | 双向bfs+康拓展开)
The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...
- POJ 3170 Knights of Ni (暴力,双向BFS)
题意:一个人要从2先走到4再走到3,计算最少路径. 析:其实这个题很水的,就是要注意,在没有到4之前是不能经过3的,一点要注意.其他的就比较简单了,就是一个双向BFS,先从2搜到4,再从3到搜到4, ...
- POJ 3126 Prime Path 解题报告(BFS & 双向BFS)
题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...
- POJ 1915-Knight Moves (单向BFS && 双向BFS 比)
主题链接:Knight Moves 题意:8个方向的 马跳式走法 ,已知起点 和终点,求最短路 研究了一下双向BFS,不是非常难,和普通的BFS一样.双向BFS只是是从 起点和终点同一时候開始搜索,可 ...
- [poj] 2549 Sumsets || 双向bfs
原题 在集合里找到a+b+c=d的最大的d. 显然枚举a,b,c不行,所以将式子移项为a+b=d-c,然后双向bfs,meet int the middle. #include<cstdio&g ...
- POJ——3126Prime Path(双向BFS+素数筛打表)
Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16272 Accepted: 9195 Descr ...
随机推荐
- TVS二极管的主要参数与选型
TVS二极管的主要参数--转载 处理瞬时脉冲对器件损害的最好办法是将瞬时电流从敏感器件引开.TVS二极管在线路板上与被保护线路并联,当瞬时电压超过电路正常工作电压后,TVS二极管便发生雪崩,提供给瞬时 ...
- Android基础总结(七)BroadcastReceiver
广播(掌握) 广播的概念 现实:电台通过发送广播发布消息,买个收音机,就能收听 Android:系统在产生某个事件时发送广播,应用程序使用广播接收者接收这个广播,就知道系统产生了什么事件. Andro ...
- TF和SD
TF卡又称T-Flash卡,全名:TransFLash,又名:Micro SD SD卡(Secure Digital Memory Card,安全数码卡)
- 关于VS2013的安装遇到的问题
老师突然说实验一需要用代码实现,我之前配置的cocos的编程环境是cocos+VS2013,是很稳定的 但是,我安装unity5.5的时候,不小心选择了顺带安装了VS2015,就等于我电脑里面有了两个 ...
- 出错的方法有可能是JDK,也可能是程序员写的程序,无论谁写的,抛出一定用throw
应对未检查异常就是养成良好的检查习惯. 已检查异常是不可避免的,对于已检查异常必须实现定义好应对的方法. 已检查异常肯定跨越出了虚拟机的范围.(比如“未找到文件”) 如何处理已检查异常(对于所有的已检 ...
- php -- 文件操作(创建、复制、移动、删除)
创建 文件夹 bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = false [, resource $con ...
- 【BZOJ】1662: [Usaco2006 Nov]Round Numbers 圆环数(数位dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1662 这道题折腾了我两天啊-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 果然 ...
- MFC通过button控制编辑框是否显示系统时间(动态显示)
1.在dlg.h中public bool flag; static UINT time(void *param); 2.在构造函数中 flag=false; 3.在button的生成函数中 if(fl ...
- storm的集群安装与配置
storm集群安装 机器:(storm及zookeeper都是这3台机器) 192.168.80.20 192.168.80.21 192.168.80.22 须要准备的软件有: zookeeper( ...
- hrbustoj 1142:围困(计算几何基础题,判断点是否在三角形内)
围困 Time Limit: 1000 MS Memory Limit: 65536 K Total Submit: 360(138 users) Total Accepted: 157(12 ...