题目描述 Description
Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.
问题描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
输入描述 Input Description
输入初试状态,一行九个数字,空格用0表示
输出描述 Output Description
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)
样例输入 Sample Input
283104765
样例输出 Sample Output
4
数据范围及提示 Data Size & Hint
详见试题
注意 :map会超时(我指的是单向bfs);
新东西,康拓展开;
ll cantor(hh xs)
{
ll num=0;
for(ll i=1;i<=9;i++)
{
ll tmp=0;
for(ll j=i+1;j<=9;j++)
if(xs.a[i]>xs.a[j]) tmp++;
num+=tmp*fac[9-i];
}
return num;
}
把一个整数X展开成如下形式:
X=a[n](n-1)!+a[n-1](n-2)!+…+a[i]*(i-1)!+…+a[2]*1!+a[1]*0!
其中a[i]为当前未出现的元素中是排在第几个(从0开始),并且0<=a[i]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
char s[10];
typedef unsigned long long ll;
bool vis[10000001];
ll fac[10]={1,1,2,6,24,120,720,5040,40320,362880},la,t;
ll X[]={0,1,-1,0,0};
ll Y[]={0,0,0,-1,1};
struct hh
{
ll x,y,a[10],step;
};
ll cantor(hh xs)
{
ll num=0;
for(ll i=1;i<=9;i++)
{
ll tmp=0;
for(ll j=i+1;j<=9;j++)
if(xs.a[i]>xs.a[j]) tmp++;
num+=tmp*fac[9-i];
}
return num;
}
queue<hh>q;
hh start,js,now,u;
bool can(ll fx,ll fy)
{
if(fx>=1 && fx<=3 && fy>=1 && fy<=3) return true;
return false;
}
void bfs()
{
while(!q.empty())
{
u=q.front();
q.pop();
if(cantor(u)==la) {cout<<u.step<<endl;return;}
for(ll i=1;i<=4;i++)
{
now=u;
now.x=X[i]+u.x;
now.y=Y[i]+u.y;
if(can(now.x,now.y))
{
now.a[u.x*3+u.y-3]=now.a[now.x*3+now.y-3];
now.a[now.x*3+now.y-3]=0;
now.step=u.step+1;
if(!vis[cantor(now)]) vis[cantor(now)]=1,q.push(now);
if(cantor(now)==la) {cout<<now.step<<endl;return;}
}
}
}
return;
}
void init()
{
for(ll i=1;i<=9;i++) start.a[i]=s[i]-'0';
for(ll i=1;i<=9;i++)
{
if(start.a[i]==0)
{
if(i==1) start.x=1,start.y=1;
else if(i==2) start.x=1,start.y=2;
else if(i==3) start.x=1,start.y=3;
else if(i==4) start.x=2,start.y=1;
else if(i==5) start.x=2,start.y=2;
else if(i==6) start.x=2,start.y=3;
else if(i==7) start.x=3,start.y=1;
else if(i==8) start.x=3,start.y=2;
else if(i==9) start.x=3,start.y=3;
break;
}
}
start.step=0;
vis[cantor(start)]=1;
q.push(start);
js.a[1]=1,js.a[2]=2,js.a[3]=3,js.a[4]=8,js.a[5]=0;
js.a[6]=4,js.a[7]=7,js.a[8]=6,js.a[9]=5;
la=cantor(js);
return;
}
void solve()
{
cin>>s+1;
init();
bfs();
return;
}
int main()
{
solve();
return 0;
}