UVa10085 - The most distant state

#include <stdio.h>
#include <string.h>

#define N 3
#define MAX 3000000
#define HASHSIZE 1000003
#define DIRSIZE 100
typedef struct node
{
    int x, y, step;
    int a[N][N];
    char dir[DIRSIZE];
}node;

node queue[MAX];
int startx, starty;
int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};
int head[HASHSIZE], next[MAX];
char dir[] = "RLUD";

int bfs();
void init_loopup_table();
int try_to_insert(int s);
int hash(node s);
void print(node s);

int main()
{
    int iCase;
    int i, j, cas;
    int ans;

    #ifndef ONLINE_JUDGE
        freopen("d:\\UVa\\uva_in.txt", "r", stdin);
    #endif

    scanf("%d", &iCase);

    for (cas = 0; cas < iCase; cas++) {
        for (i = 0; i < N; i++) {
            for (j = 0; j < N; j++) {
                scanf("%d", &queue[0].a[i][j]);
                if (queue[0].a[i][j] == 0)
                    startx = i, starty = j;
            }
        }



        ans = bfs() - 1;

        printf("Puzzle #%d\n", cas + 1);

        for (i = 0; i < N; i++) {
            for (j = 0; j < N; j++) {
                if (j)
                    printf(" ");
                printf("%d", queue[ans].a[i][j]);
            }
            printf("\n");
        }
        queue[ans].dir[queue[ans].step] = '\0';
        printf("%s\n", queue[ans].dir);
        printf("\n");
    }

    return 0;
}


int bfs()
{
    int front = 0, rear = 1;
    node tmp, newstate;
    int i;
    int newx, newy, tmpx, tmpy;



    queue[0].x = startx, queue[0].y = starty, queue[0].step = 0;
    init_loopup_table();

    while (front < rear) {
        tmp = queue[front];
        for (i = 0; i < 4; i++) {
            tmpx = tmp.x;
            tmpy = tmp.y;
            newx = tmpx + dx[i];
            newy = tmpy + dy[i];

            if (newx >= 0 && newx < 3 && newy >= 0 && newy < 3) {
                newstate = tmp;
                newstate.a[newx][newy] = tmp.a[tmpx][tmpy];
                newstate.a[tmpx][tmpy] = tmp.a[newx][newy];
                newstate.x = newx;
                newstate.y = newy;
                newstate.step++;
                newstate.dir[newstate.step - 1] = dir[i];
                queue[rear] = newstate;

                if (try_to_insert(rear)) {
                    rear++;
                }
            }
        }

        front++;
    }

    return rear;
}


void init_loopup_table()
{
    memset(head, -1, sizeof(head));
    memset(next, -1, sizeof(next));
    try_to_insert(0);
}

int hash(node s)
{
    int i, j;
    int res = 0;

    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            res = res * 10 + s.a[i][j];
        }
    }

    return res % HASHSIZE;
}

int try_to_insert(int s)
{
    int h = hash(queue[s]);
    int u = head[h];

    while (u != -1) {
        if (memcmp(queue[u].a, queue[s].a, sizeof(queue[s].a)) == 0)
            return 0;
        u = next[u];
    }

    next[s] = head[h];
    head[h] = s;

    return 1;
}


void print(node s)
{
    int i, j;

    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++) {
            printf("%d ", s.a[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值