首页 > 其他 > 详细

wikioi 1225 八数码难题 IDA*

时间:2014-05-11 06:19:59      阅读:491      评论:0      收藏:0      [点我收藏+]

为什么就是跑不出0ms

八数码0.0,我又来水博客了。

IDA*算法,A*为曼哈顿距离,判重用康拓展开。


#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int a[4][4];
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
char s[]="123804765";
int end[4][4];
int x,y;
int dep;
bool vis[400000];
int ca[]={1,1,2,6,24,120,720,5040,40320,362880};
inline int cantor()
{
    int sum=0;
    for(int i=0;i<9;i++)
    {
        int num=0;
        for(int j=i+1;j<9;j++)
          if(a[i/3][i%3]<a[j/3][j%3]) num++;
        sum+=(num*ca[9-i-1]);
    }
    return sum+1;
}
struct node
{
    int x,y;
}p[12];
inline bool ok()           //判断是否结束
{
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            if(p[a[i][j]].x!=i||p[a[i][j]].y!=j) return false;
        }
    }
    return true;
}
inline int dist(int x1,int y1,int x2,int y2)//求两点的曼哈顿距离
{
    return abs(x1-x2)+abs(y1-y2);
}
int h()     //求估价值
{
    int l=0;
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            if(a[i][j]==0) continue;
            l+=dist(i,j,p[a[i][j]].x,p[a[i][j]].y);
        }
    }
    return l;
}
bool dfs(int now,int x,int y)       //(x,y)保存0的位置
{
    if(ok()) return true;
    if(now+h()>dep) return false;
    for(int d=0;d<4;d++)
    {
        int nx=x+dx[d];
        int ny=y+dy[d];
        if(nx>=0&&nx<3&&ny>=0&&ny<3)
        {
            int can=cantor();
            if(vis[can]) continue;
            vis[can]=true;
            swap(a[nx][ny],a[x][y]);
            if(dfs(now+1,nx,ny)) return true;
            swap(a[nx][ny],a[x][y]);
            vis[can]=false;
        }
    }
    return false;
}
char str[12];
int main()
{
    scanf("%s",str);
    for(int i=0,b=0;i<3;i++)
    {
        for(int j=0;j<3;b++,j++)
        {
            p[s[b]-‘0‘].x=i;    //记录目标数字对应的位置
            p[s[b]-‘0‘].y=j;
            a[i][j]=str[b]-‘0‘;
            if(!a[i][j])
            {
                x=i;
                y=j;
            }
        }
    }
    cantor();
    for(dep=h();;dep++)       //迭代加深搜索
    {
        if(dfs(0,x,y)) break;
    }
    printf("%d\n",dep);
    return 0;
}


wikioi 1225 八数码难题 IDA*,布布扣,bubuko.com

wikioi 1225 八数码难题 IDA*

原文:http://blog.csdn.net/t1019256391/article/details/25502545

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!