説明
15パズルは、100年以上前から出回っています。あなたがその名前によってそれを知らない場合でも、あなたはそれを見てきました。これは、その上に1から15まで番号をそれぞれ、15枚のスライドタイルで構成され、すべてが不足しているつのタイルと4フレームによって4に充填されています。レッツ・コール欠けているタイル「X」; パズルの目的は、彼らは次のように命じられるようにタイルを配置することです。
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x
唯一の法的操作は、それがエッジを共有するタイルの一つに「X」を交換する場所です。一例として、移動の以下の配列はわずかにスクランブルパズルを解きます。
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
r-> d-> r->
前の行の文字は、各ステップで「X」タイルと交換された「X」タイルの隣接示します。正当な値は、 'R'、 'L' は、 'U' と 'D'、それぞれ、アップ、ダウン、左、右用。
すべてのパズルを解くことができるわけではありません。1870年に、サム・ロイドという男は、パズルの解決不可能なバージョンを配布し、で有名だった
多くの人をイライラ。実際には、あなたは解けないものに定期的なパズルを作るためにしなければならないすべては、(当然の行方不明「X」のタイルを、カウントしない)スワップに2枚のタイルれます。
この問題では、3×3のタイルで構成さあまり知られ、8パズル、解決するためのプログラム書き込みます
配置を。
入力
あなたは8パズルの構成の説明を受けます。説明は、上から下にリストされている行と、その初期位置におけるタイルのリストだけで、タイルが8に番号1で表される、プラス「X」れる行、内左から右に記載されているタイル。たとえば、このパズル
1 2 3
x 4 6
7 5 8
このリストで説明されています。
1 2 3 x 4 6 7 5 8
出力
あなたは、標準出力のいずれかの単語 `「`解決不可能に印刷され、R」、「l「のパズルは何の解決策を持っていない場合、または文字から完全に構成される文字列」」、「U」と「のシリーズを記述D」溶液を生成動きます。文字列にはスペースを含めず、行の先頭で開始する必要があります。
サンプル入力
2 3 4 1 5 x 7 6 8
サンプル出力
ullddrurdllurdruldr
ソース
南中部USA 1998
問題の解決策
この問題は、最初の質問の意味を理解する必要があり、私は1つのアップしました...
これは、実際には8つのデジタル問題ですが、私は使用\(BFS + Aを* \) 、この質問\(A * \)剪定の基本的貪欲使用であり、
所定の状態と各数の推定値は、その目標位置マンハッタン距離であろう
我々は再文に持っているので、サイクルとして、発生する可能性があり、このタイトルのために、\(ハッシュは\)良い選択です
(ハッシュ\)\、私たちが展開カントールを使用
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
#include<iomanip>
#include<set>
#include<map>
using namespace std;
struct node
{
int f,g,id[10],mp[10];
string s;
bool operator< (const node &tmp) const
{
return f>tmp.f;
}
};
node q;
priority_queue<node> Q;
int d[10][10],goal[10];
int fac[9]={1,2,6,24,120,720,5040,40320,362880};
bool Hash[362881];
void Init()
{
for(int i=1;i<=3;++i)
for(int j=1;j<=3;++j)
for(int x=1;x<=3;++x)
for(int y=1;y<=3;++y)
d[(i-1)*3+j][(x-1)*3+y]=abs(i-x)+abs(j-y);
goal[0]=9,goal[1]=1,goal[2]=2,
goal[3]=3,goal[4]=4,goal[5]=5,
goal[6]=6,goal[7]=7,goal[8]=8;
}
void Read()
{
char c;
for(int i=1;i<=9;++i)
{
c=getchar();
while(c==' ') c=getchar();
if(c=='x') q.id[0]=i,q.mp[i]=0;
else q.id[(c^48)]=i,q.mp[i]=(c^48);
}
}
bool Check()
{
for(int i=0;i<=8;++i)
if(goal[i]!=q.id[i]) return 0;
return 1;
}
int A_star(node nx)
{
int Res=0;
for(int i=0;i<=8;++i) Res+=d[nx.id[i]][goal[i]];
return Res;
}
int Calc(node nx)
{
int Res=0,c;
for(int i=0;i<8;++i)
{
c=0;
for(int j=i+1;j<=8;++j)
if(nx.id[i]>nx.id[j]) ++c;
Res+=c*fac[i];
}
return Res;
}
void BFS()
{
Q.push(q);
Hash[Calc(q)]=1;
node nx;
int YouHua;
while(!Q.empty())
{
q=Q.top(); Q.pop();
if(Check())
{
cout<<q.s<<endl;
return;
}
if(q.id[0]<7)
{
nx=q,
nx.g=q.g+1,
nx.mp[q.id[0]]=q.mp[q.id[0]+3],
nx.mp[q.id[0]+3]=0,
nx.id[0]=q.id[0]+3,
nx.id[q.mp[q.id[0]+3]]=q.id[0],
YouHua=Calc(nx);
if(!Hash[YouHua])
{
Hash[YouHua]=1,
nx.s=q.s+'d',
nx.f=nx.g+A_star(nx);
Q.push(nx);
}
}
if(q.id[0]%3!=1)
{
nx=q,
nx.g=q.g+1,
nx.mp[q.id[0]]=q.mp[q.id[0]-1],
nx.mp[q.id[0]-1]=0,
nx.id[0]=q.id[0]-1,
nx.id[q.mp[q.id[0]-1]]=q.id[0],
YouHua=Calc(nx);
if(!Hash[YouHua])
{
Hash[YouHua]=1,
nx.s=q.s+'l',
nx.f=nx.g+A_star(nx);
Q.push(nx);
}
}
if(q.id[0]%3)
{
nx=q,
nx.g=q.g+1,
nx.mp[q.id[0]]=q.mp[q.id[0]+1],
nx.mp[q.id[0]+1]=0,
nx.id[0]=q.id[0]+1,
nx.id[q.mp[q.id[0]+1]]=q.id[0],
YouHua=Calc(nx);
if(!Hash[YouHua])
{
Hash[YouHua]=1,
nx.s=q.s+'r',
nx.f=nx.g+A_star(nx);
Q.push(nx);
}
}
if(q.id[0]>3)
{
nx=q,
nx.g=q.g+1,
nx.mp[q.id[0]]=q.mp[q.id[0]-3],
nx.mp[q.id[0]-3]=0,
nx.id[0]=q.id[0]-3,
nx.id[q.mp[q.id[0]-3]]=q.id[0],
YouHua=Calc(nx);
if(!Hash[YouHua])
{
Hash[YouHua]=1,
nx.s=q.s+'u',
nx.f=nx.g+A_star(nx);
Q.push(nx);
}
}
}
}
int main()
{
Init(),Read(),BFS();
return 0;
}