Description
The 15-puzzle has been around for over 100 years; even if you don’t know it by that name, you’ve seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let’s call the missing tile ‘x’; the object of the puzzle is to arrange the tiles so that they are ordered as:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x
where the only legal operation is to exchange ‘x’ with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:
1 2 3 4
5 6 7 8
9 x 10 12
13 14 11 15
r->
1 2 3 4
5 6 7 8
9 10 x 12
13 14 11 15
d->
1 2 3 4
5 6 7 8
9 10 11 12
13 14 x 15
r->
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x
The letters in the previous row indicate which neighbor of the ‘x’ tile is swapped with the ‘x’ tile at each step; legal values are ‘r’,‘l’,‘u’ and ‘d’, for right, left, up, and down, respectively.
Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing ‘x’ tile, of course).
In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three arrangement.
Input
You will receive, several descriptions of configuration of the 8 puzzle. One description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus ‘x’. For example, this puzzle
1 2 3
x 4 6
7 5 8
is described by this list:
1 2 3 x 4 6 7 5 8
Output
You will print to standard output either the word ``unsolvable’’, if the puzzle has no solution, or a string consisting entirely of the letters ‘r’, ‘l’, ‘u’ and ‘d’ that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line. Do not print a blank line between cases.
Sample input
2 3 4 1 5 x 7 6 8
Sample output
ullddrurdllurdruldr
分析
x 可以与它 上 下 左 右 数字交换位置,搜索是否能得到 “”12345678x“”, 找到则输出 交换过程 ,找不到 则输出 “unsolvable”。
把 x 当成 0 看待,所以有每个位置有九种可能,共九个位置,无法用普通数组标记。
可以用 map<int,string> 这种形式的map容器进行表示,从初始状态到达 int 状态经历的路径string。
如果,根据题目给定的初始状态去找“”123456780“”,超时。因为,需要找的最终状态是“”123456780“”,
所以,把“123456780”当成初状态,去找所能到达的状态,只需要bfs()一次,把所有能到达的状态打一次表,对于每次询问,查找int键值是否存在,存在则输出是反向输出,u和d,l和r交换输出,不存在,unsolvable。
代码
// An highlighted block
var foo = 'bar';
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
map<int,string>v;
struct node
{
string a,s;
int x;
};
void bfs()
{
node now,net;
queue<node>Q;
now.a="123456780";
now.s="";
now.x=8;
v[123456780]="";
Q.push(now);
while(!Q.empty())
{
now=Q.front();
Q.pop();
for(int i=1; i<=4; i++)
{
char p;
int fg=0,dx=now.x;
if(i==1&&now.x+3<=8)
dx=now.x+3,p='u',fg=1;
else if(i==2&&now.x-3>=0)
dx=now.x-3,p='d',fg=1;
else if(i==3&&now.x%3>=1)
dx=now.x-1,p='r',fg=1;
else if(i==4&&now.x%3<=1)
dx=now.x+1,p='l',fg=1;
if(!fg) continue;
net=now;
swap(net.a[now.x],net.a[dx]);
int d=0;
for(int j=0; j<9; j++)
d=d*10+net.a[j]-'0';
if(v.find(d)==v.end())
{
net.s+=p;
net.x=dx;
v[d]=net.s;
Q.push(net);
}
}
}
}
int main()
{
bfs();
char c[5];
string c1;
while(~scanf("%s",c))
{
int i,d=0;
if(c[0]=='x')
d=d*10+0;
else
d=d*10+c[0]-'0';
for(i=1; i<9; i++)
{
scanf("%s",c);
if(c[0]=='x')
d=d*10+0;
else
d=d*10+c[0]-'0';
}
if(v.find(d)!=v.end())
{
c1=v[d];
for(i=c1.size()-1; i>=0; i--)
cout<<c1[i];
cout<<endl;
}
else
cout<<"unsolvable"<<endl;
}
return 0;
}