uva 10085 The most distant state

题目地址:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1026

题目描述:

The 8-puzzle is a square tray in which eight square tiles are placed. The remaining ninth square is
uncovered. Each tile has a number on it. A tile that is adjacent to the blank space can be slid into
that space. A game consists of a starting state and a specified goal state. The starting state can be
transformed into the goal state by sliding (moving) the tiles around. The 8-puzzle problem asks you to
do the transformation in minimum number of moves.
2 8 3
1 6 4
7 0 5
=>
1 2 3
8 0 4
7 6 5
Start Goal
However, our current problem is a bit different. In this problem, given an initial state of the puzzle
your are asked to discover a goal state which is the most distant (in terms of number of moves) of all
the states reachable from the given state.
Input
The first line of the input file contains an integer representing the number of test cases to follow. A
blank line follows this line.
Each test case consists of 3 lines of 3 integers each representing the initial state of the puzzle. The
blank space is represented by a ‘0’ (zero). A blank line follows each test case.
Output
For each test case first output the puzzle number. The next 3 lines will contain 3 integers each
representing one of the most distant states reachable from the given state. The next line will contain
the shortest sequence of moves that will transform the given state to that state. The move is actually
the movement of the blank space represented by four directions: ‘U’ (Up), ‘L’ (Left), ‘D’ (Down) and
‘R’ (Right).
After each test case output an empty line.
Sample Input
1
2 6 4
1 3 7
0 5 8
Sample Output
Puzzle #1
8 1 5
7 3 6
4 0 2
UURDDRULLURRDLLDRRULULDDRUULDDR

题意:

求源状态的最远的目标状态。

题解:

这道题还是栽在hash上了,本来一开始我想直接开一个大小为876543210的数组来标记哪些状态标记过,哪些状态没有标记过,但是其运行的实际效果却要很长时间,尽管这样代码的hash策略足够的简单,也可以说是一个完美一一对应的hash,但是实际运行效果还是慢!!无奈换成lrj 书上八数码的hash链表,时间却降下来了,在这里似乎程序的运行时间不仅仅取决于代码的逻辑结构(尽管的hash策略足够简单,甚至都没有各式各样的循环),并且还取决于代码的空间占用。当你试着调整我代码中关于队列 hash链表大小的设置时 不同的大小其运行的时间也是不一样的。

代码:

#include<stdio.h>
#include<string.h>
#define MM 400000
int N=0,cases=0;
typedef struct state
{
    int maze[3][3];
    char path[100];
    int zx;
    int zy;
    int len;
    state()
    {
        memset(path, '\0', sizeof(path));
        len = 0;
    }
}state, * state_link; 
state sque[MM];
int head = 0, rear = 0;
state sur,des;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int head_hash[MM],next_hash[MM];
int queue_clear()
{
    head = 0;
    rear = 0;
    return(0);
}
int push(state & elem)
{
    sque[rear++] = elem;
    return(0);
}
bool queue_empty()
{
    if(head > rear) return true;
    else return false;
}
state pop()
{
    return sque[head++];
}
int set_zxzy(state & elem)
{
    for(int i = 0; i <= 2; i++)
        for(int j = 0; j <= 2; j++)
            if(elem.maze[i][j] == 0)
            {
                elem.zx = i;
                elem.zy = j;
                return 0;
            }
    return 0;
}
int mv_state(state & elem, int i)
{
    char ch = 'U';
    int nx = 0, ny = 0;
    switch(i)
    {
    case 0:
        ch ='R';
        nx = elem.zx;
        ny = elem.zy + 1;
        break;
    case 1:
        ch = 'L';
        nx = elem.zx;
        ny = elem.zy - 1;
        break;
    case 2:
        ch = 'D';
        nx = elem.zx + 1;
        ny = elem.zy;
        break;
    case 3:
        ch = 'U';
        nx = elem.zx - 1;
        ny = elem.zy;
        break;
    }
    elem.maze[elem.zx][elem.zy] = elem.maze[nx][ny];
    elem.maze[nx][ny] = 0;
    elem.zx = nx;
    elem.zy = ny;
    elem.path[elem.len] = ch;
    elem.len++;
    elem.path[elem.len] = '\0';
    return(0);
}
int un_mv_state(state & elem, int i)
{
    switch(i)
    {
    case 0:
        mv_state(elem, 1);
        break;
    case 1:
        mv_state(elem, 0);
        break;
    case 2:
        mv_state(elem, 3);
        break;
    case 3:
        mv_state(elem, 2);
        break;
    }
    elem.len-=2;
    elem.path[elem.len] = '\0';
    return 0;
}
int get_hash(state & elem)
{
    int code = 0;
    for(int i = 0; i <= 9 - 1; i++)
        code = code * 10 + elem.maze[i/3][i%3];
    return code % MM;
}
bool is_visit(state & elem)
{
    int addr_ins = rear;
    int hash_code = get_hash(elem);
    int addr = head_hash[hash_code];
    while(addr)
    {
        if(memcmp(elem.maze, sque[addr].maze, sizeof(elem.maze)) == 0) return true;//find it!!
        addr = next_hash[addr];
    }
    next_hash[addr_ins] = head_hash[hash_code];
    head_hash[hash_code] = addr_ins;
    return false;//not find and insert it
}
int update_des(state & elem)
{
    if(elem.len > des.len) des = elem;
    return 0;
}
int BFS()
{
    while(!queue_empty())
    {
        state elem = pop();
        int ava_cnt = 0;
        for(int i = 0; i <= 4 - 1; i++)
        {
            int nx = elem.zx + dx[i];
            int ny = elem.zy + dy[i];
            if(nx >=0 && nx <= 2 && ny >= 0 && ny <= 2)
            {
                mv_state(elem, i);
                if(!is_visit(elem))
                {
                    ava_cnt ++;
                    push(elem);
                }
                un_mv_state(elem,i);
            }
        }
        if(ava_cnt == 0) update_des(elem);
    }
    return(0);
}
int print_state(state & elem)
{
    printf("%d %d %d\n",elem.maze[0][0], elem.maze[0][1], elem.maze[0][2]);
    printf("%d %d %d\n",elem.maze[1][0], elem.maze[1][1], elem.maze[1][2]);
    printf("%d %d %d\n",elem.maze[2][0], elem.maze[2][1], elem.maze[2][2]);
    printf("%s\n",elem.path);
    return 0;
}
int main()
{
    scanf("%d",&N);
    while(N--)
    {
        cases++;
        memset(des.path,'\0',sizeof(des.path));
        memset(head_hash, 0, sizeof(head_hash));
        memset(next_hash, 0, sizeof(next_hash));
        des.len = 0;
        scanf("%d%d%d",&sur.maze[0][0],&sur.maze[0][1],&sur.maze[0][2]);
        scanf("%d%d%d",&sur.maze[1][0],&sur.maze[1][1],&sur.maze[1][2]);
        scanf("%d%d%d",&sur.maze[2][0],&sur.maze[2][1],&sur.maze[2][2]);
        set_zxzy(sur);
        queue_clear();
        push(sur);
        BFS();
        printf("Puzzle #%d\n",cases);
        print_state(des);
        printf("\n");
    }
    return(0);
}

猜你喜欢

转载自blog.csdn.net/hackerwin7/article/details/44083123