uva10085 - The most distant state

来源:互联网 发布:mysql主键 增加 编辑:程序博客网 时间:2024/06/16 03:55

bfs  +  哈希技术,,,

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

#include <cstdio>#include <cstring>#define MAX 1000000int 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 800000int 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;}


原创粉丝点击