uva10085 - The most distant state

bfs  +  哈希技术,,,

超经典,超高效代码:::

#include <cstdio>
#include <cstring>
#define MAX 1000000
int ans, st[MAX][9], head[MAX], next[MAX], posi[MAX], fa[MAX], path[MAX];
int dx[4] = {-1,1,0,0}, dy[4] = {0,0,-1,1};
char dir[4] = {'U','D','L','R'};
int hash(int *A)
{
    int v = 0;
    for(int i = 0; i < 9; i++) v = v * 10 + A[i];
    return v%MAX;
}
int try_to_insert(int s)
{
    int h = hash(st[s]);
    int u = head[h];
    while(u)
    {
        if(memcmp(st[u], st[s],sizeof(st[s]))==0) return 0;
        u = next[u];
    }
    next[s] = head[h];
    head[h] = s;
    return 1;
}
void bfs(int p)
{
    memset(head,0,sizeof(head));
    memset(next,0,sizeof(head));
    int rear = 0, front = 1;
    posi[0] = p;
    try_to_insert(0);
    while(rear<front)
    {
        int x = posi[rear]/3, y = posi[rear]%3;
        for(int i = 0; i < 4; i++) if(x+dx[i]>=0&&x+dx[i]<3&&y+dy[i]>=0&&y+dy[i]<3)
        {
            int op = posi[rear], np = (x+dx[i])*3+y+dy[i];
            memcpy(st[front],st[rear],sizeof(st[rear]));
            st[front][op] = st[rear][np];
            st[front][np] = st[rear][op];
            if(try_to_insert(front))
            {
                posi[front] = (x+dx[i])*3+y+dy[i];
                fa[front] = rear;
                path[front] = i;
                front++;
            }
        }
        rear++;
    }
    ans = front-1;
}
void print_path(int cur)
{
    if(cur)
    {
        print_path(fa[cur]);
        printf("%c",dir[path[cur]]);
    }
}
int main ()
{
    int t, p, cas = 0;
    scanf("%d",&t);
    while(t--)
    {
        for(int i = 0; i < 9; i++) { scanf("%d",&st[0][i]); if(st[0][i]==0) p = i;}
        bfs(p);
        printf("Puzzle #%d\n",++cas);
        for(int i = 0; i < 3; i++)
        {
            printf("%d %d %d", st[ans][3*i], st[ans][3*i+1], st[ans][3*i+2]);
            printf("\n");
        }
        print_path(ans);
        printf("\n\n");
    }
    return 0;
}



还有编码方法。。就是9个数共有9!种排列,每一种排列都编上号,用vis数组来记录。。。。

代码如下:

#include <cstdio>
#include <cstring>
#define MAX 800000
int ans, st[MAX][9], vis[362880], posi[MAX], fa[MAX], path[MAX];
int dx[4] = {-1,1,0,0}, dy[4] = {0,0,-1,1}, fact[10] = {1,1,2,6,24,120,720,5040,40320,362880};
char dir[4] = {'U','D','L','R'};
int return_position(int s)
{
    int code = 0;
    for(int i = 0, u = 0; i < 9; i++)
    {
        for(int j = i+1; j < 9; j++) if(st[s][i]>st[s][j]) u++;
        code+=fact[8-i]*u;
        u = 0;
    }
    return code;
}
void bfs(int p)
{
    memset(vis,0,sizeof(vis));
    int rear = 0, front = 1;
    posi[0] = p;
    while(rear<front)
    {
        int x = posi[rear]/3, y = posi[rear]%3;
        for(int i = 0; i < 4; i++) if(x+dx[i]>=0&&x+dx[i]<3&&y+dy[i]>=0&&y+dy[i]<3)
        {
            int op = posi[rear], np = (x+dx[i])*3+y+dy[i];
            memcpy(st[front],st[rear],sizeof(st[rear]));
            st[front][op] = st[rear][np];
            st[front][np] = st[rear][op];
            if(!vis[return_position(front)])
            {
                vis[return_position(front)] = 1;
                posi[front] = (x+dx[i])*3+y+dy[i];
                fa[front] = rear;
                path[front] = i;
                front++;
            }
        }
        rear++;
    }
    ans = front-1;
}
void print_path(int cur)
{
    if(cur)
    {
        print_path(fa[cur]);
        printf("%c",dir[path[cur]]);
    }
}
int main ()
{
    int t, p, cas = 0;
    scanf("%d",&t);
    while(t--)
    {
        for(int i = 0; i < 9; i++) { scanf("%d",&st[0][i]); if(st[0][i]==0) p = i;}
        bfs(p);
        printf("Puzzle #%d\n",++cas);
        for(int i = 0; i < 3; i++)
        {
            printf("%d %d %d", st[ans][3*i], st[ans][3*i+1], st[ans][3*i+2]);
            printf("\n");
        }
        print_path(ans);
        printf("\n\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值