hdu 1043 #八数码#全排列逆序对的哈希+BFS

之前这题超时的,因为每次都BFS了。

当时实在是蠢了,其实只要以终态为起点一次BFS就记录好所有路径了


#include 
#include 
#include 
#include 
using namespace std;
#define N 1000000
struct node
{
    int x,y;
    char mat[3][3];
}p,pt;

char dir[N];
int nxt[N];
int move[][2] = {0,1,1,0,0,-1,-1,0};
char mo[5] = "lurd";
int fac[] = {1,1,2,6,24,120,720,5040,40320};

bool inner(int x,int y)
{
    return x >=0 && x < 3 && y >=0 && y < 3;
}
int get_hash(node p)
{
    int i,j,k,ans = 0,d;
    char temp[10];
    for(i = 0; i < 3; ++i)
        for(j = 0; j < 3; ++j)
        {
            temp[i*3+j] = p.mat[i][j];
            d = 0;
            for(k = 0; k < i * 3 + j; ++k)
                if(temp[k] > p.mat[i][j])
                    ++d;
            ans += fac[i*3+j] * d;
        }
    return ans;
}
void bfs()
{
    for(int i = 0; i < 3; ++i)
        for(int j = 0; j < 3; ++j)
            p.mat[i][j] = '1' +  i * 3 + j;
    p.mat[2][2] = '0';
    p.x = p.y = 2;

    memset(nxt,-1,sizeof(nxt));
    queue que;
    que.push(p);
    int hh,h = get_hash(p);
    nxt[h] = -2;
    dir[h] = '\n';
    while(!que.empty())
    {
        p = que.front();
        que.pop();
        h = get_hash(p);
        for(int i = 0; i < 4; ++i)
        {
            pt = p;
            pt.x += move[i][0];
            pt.y += move[i][1];
            if(inner(pt.x,pt.y))
            {
                swap(pt.mat[p.x][p.y],pt.mat[pt.x][pt.y]);
                hh = get_hash(pt);
                if(nxt[hh] == -1)
                {
                    nxt[hh] = h;
                    dir[hh] = mo[i];
                    que.push(pt);
                }
            }
        }
    }
}
int main()
{
    bfs();
    int i,j;
    while(cin >> p.mat[0][0])
    {
        cin >> p.mat[0][1] >> p.mat[0][2];
        for(i = 1; i < 3; ++i)
            for(j = 0; j < 3; ++j)
                cin >>p.mat[i][j];
        for(i = 0; i < 3; ++i)
            for(j = 0; j < 3; ++j)
                if(p.mat[i][j] == 'x')
                    p.mat[i][j] = '0';

        int h = get_hash(p);
        if(nxt[h] == -1)
            printf("unsolvable\n");
        else
        {
            for(; nxt[h] != -2; h = nxt[h])
                printf("%c",dir[h]);
            printf("\n");
        }
    }
    return 0;
}



#include
#include
#include
#include
#include
using namespace std;

char ms[6]="rdul";
int vis[400000],id;
int pre[600000];
char path[600000];
int fac[]={1,1,2,6,24,120,720,5040,40320};


struct node
{
    int pos,id;
    int s[9];
}p,p2;
int hash(int *str)
{
    int i,j,cnt,res=0,jac=1;
    for(i=1;i<9;++i)
    {
        cnt=0;
        for(j=0;jstr[i])
                ++cnt;
        res+=cnt*fac[i];
    }
    return res;
}
void output(int s)
{
    char str[400000];
    int k=0;
    while(s)
    {
        str[k++]=path[s];
        s=pre[s];
    }
    for(k--;k>=0;--k)
        printf("%c",str[k]);
    printf("\n");
}
//int final=hash("123456789");//终态的哈希值为0
int bfs()
{
    queue que;
    int h;

    h=hash(p.s);
    if(!h)
    {
        printf("\n");
        return 1;
    }

    memset(vis,0,sizeof(vis));
    p.id=0;
    que.push(p);
    vis[h]=1;
    id=0;
    while(!que.empty())
    {
        p=que.front();
        que.pop();

        if(p.pos%3!=2)
        {
            p2=p;
            swap(p2.s[p.pos],p2.s[p.pos+1]);
            h=hash(p2.s);
            if(!vis[h])
            {
                vis[h]=1;
                p2.id=++id;
                pre[id]=p.id;
                path[id]=ms[0];
                if(!h)
                {
                    output(id);
                    return 1;
                }
                p2.pos=p.pos+1;
                que.push(p2);
            }
        }
        if(p.pos%3)
        {
            p2=p;
            swap(p2.s[p.pos],p2.s[p.pos-1]);
            h=hash(p2.s);

            if(!vis[h])
            {
                vis[h]=1;
                p2.id=++id;
                pre[id]=p.id;
                path[id]=ms[3];
                if(!h)
                {
                    output(id);
                    return 1;
                }
                p2.pos=p.pos-1;
                que.push(p2);
            }
        }
        if(p.pos>2)
        {
            p2=p;
            swap(p2.s[p.pos],p2.s[p.pos-3]);
            h=hash(p2.s);

            if(!vis[h])
            {
                vis[h]=1;
                p2.id=++id;
                pre[id]=p.id;
                path[id]=ms[2];
                if(!h)
                {
                    output(id);
                    return 1;
                }
                p2.pos=p.pos-3;
                que.push(p2);
            }
        }
        if(p.pos<6)
        {
            p2=p;
            swap(p2.s[p.pos],p2.s[p.pos+3]);
            h=hash(p2.s);

            if(!vis[h])
            {
                vis[h]=1;
                p2.id=++id;
                pre[id]=p.id;
                path[id]=ms[1];
                if(!h)
                {
                    output(id);
                    return 1;
                }
                p2.pos=p.pos+3;
                que.push(p2);
            }
        }
    }
    return 0;
}
int main()
{
    int i,j=0;
    char e[3];

    while(scanf("%s",e)==1)
    {
        if(e[0]=='x')
        {
            p.s[0]=9;
            p.pos=0;
        }
        else
            p.s[0]=e[0]-'0';
        for(i=1;i<9;++i)
        {
            scanf("%s",e);
            if(e[0]=='x')
            {
                p.s[i]=9;
                p.pos=i;
            }
            else
                p.s[i]=e[0]-'0';
        }
        if(!bfs())
            printf("unsolvable\n");
    }
    return 0;
}


你可能感兴趣的:(Search)