您的位置:首页 > 大数据 > 人工智能

Aizu 0121 Seven Puzzle(变进制数的完美hash)

2015-10-18 15:38 393 查看
一遍预处理跑完所有情况,O(1)回答就好。状态记录我用的康拓和逆康拓。

#include<bits/stdc++.h>
using namespace std;

int d[40320];
int fac[8];
int u[8];

int cantor()
{
int re = 0;
for(int i = 0; i < 8; i++){
int inv = 0;
for(int j = i; ++j < 8; ){
if(u[i]>u[j]) inv++;
}
re += fac[7-i]*inv;
}
return re;
}

void invCantor(int x)
{
bool vis[8] = {};
for(int i = 0; i < 8; i++){
int w = x/fac[7-i];
x %= fac[7-i];
int j = 0;
for( ; j < 8; j++){
if(!vis[j]){
if(!w) break;
w--;
}
}
u[i] = j; vis[j] = true;
}
}

int cur;
queue<int> q;

inline void updata(int p0,int p1)
{
swap(u[p0],u[p1]);
int s = cantor();
if(!d[s]){
d[s] = d[cur]+1;
q.push(s);
}
swap(u[p0],u[p1]);
}

void bfs()
{
d[0] = 1;
q.push(0);
while(q.size()){
invCantor(cur = q.front()); q.pop();
int p;
for(int i = 0; i < 8; i++)
if(!u[i]){ p = i; break; }
int r = p%4;
if(r) {
updata(p-1,p);
}
if(r<3){
updata(p+1,p);
}
updata(p,p+(p>3?-4:4));
}
}

void preDeal()
{
fac[0] = 1;
for(int i = 1; i < 8; i++){
fac[i] = fac[i-1]*i;
}
bfs();
}

int read()
{
if(scanf("%d",u)<0) return -1;
for(int i = 1; i < 8; i++) scanf("%d",u+i);
return cantor();
}

//#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
preDeal();
int s;
while( ~(s = read()) ){
printf("%d\n",d[s]-1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: