POJ 1077 Eight【广搜】

Description

The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as:
 1  2  3  4 

5 6 7 8
9 10 11 12
13 14 15 x

where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:
 1  2  3  4    1  2  3  4    1  2  3  4    1  2  3  4 

5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
r-> d-> r->

The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively.

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course).

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
arrangement.

Input

You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle
 1  2  3 

x 4 6
7 5 8

is described by this list:

1 2 3 x 4 6 7 5 8

Output

You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.

Sample Input

 2  3  4  1  5  x  7  6  8 

Sample Output

ullddrurdllurdruldr


分析:康拓展开+普通广搜。
View Code
#include<stdio.h>
#include<string.h>
int fac[10];
int pre[400000];
char dir[400000];
void print(int x)
{
    if(pre[x]!=-1)
    {
        print(pre[x]);
        printf("%c",dir[x]);
    }
}
void init()
{
    int i;
    fac[0]=1;
    for(i=1;i<=9;i++)
        fac[i]=fac[i-1]*i;
}
int contor(int s[])
{
    int i,j,t;
    int num=0;
    for(i=0;i<8;i++)
    {
        t=0;
        for(j=i+1;j<9;j++)
            if(s[j]<s[i])
                t++;
            num+=fac[8-i]*t;
    }
    return num;
}
void uncontor(int s[],int num)
{
    int i,j,t,r;
    int p[10]={0};
    for(i=0;i<9;i++)
    {
        t=num/fac[8-i]+1;
        num%=fac[8-i];
        r=0;
        j=1;
        while(1)
        {
            if(!p[j])
                r++;
            if(r==t)break;
            j++;
        }
        s[i]=j;
        p[j]=1;
    }
}
int q[400000];
int main()
{
    init();
    int s[9];
    char c[2];
    int ns,x,i,flag,front,rear;
    while(scanf("%s",c)!=EOF)
    {
        if(c[0]=='x')
            s[0]=9;
        else s[0]=c[0]-'0';
        for(i=1;i<9;i++)
        {
            scanf("%s",c);
            if(c[0]!='x')
                s[i]=c[0]-'0';
            else s[i]=9;
        }
        front=rear=0;
        memset(pre,0,sizeof(pre));
        x=contor(s);
        pre[x]=-1;
        q[rear++]=x;
        flag=0;
        while(front<rear)
        {
            x=q[front++];
            if(x==0){ flag=1;  break;}
            uncontor(s,x);
            for(i=0;i<9;i++)
                if(s[i]==9)break;
            if(i!=0&&i!=1&&i!=2)
            {
                s[i]^=s[i-3]^=s[i]^=s[i-3];
                ns=contor(s);
                if(!pre[ns])
                {
                    pre[ns]=x;
                    dir[ns]='u';
                    q[rear++]=ns;
                }
                s[i]^=s[i-3]^=s[i]^=s[i-3];
            }
            if(i!=6&&i!=7&&i!=8)
            {
                s[i]^=s[i+3]^=s[i]^=s[i+3];
                ns=contor(s);
                if(!pre[ns])
                {
                    pre[ns]=x;
                    dir[ns]='d';
                    q[rear++]=ns;
                }
                s[i]^=s[i+3]^=s[i]^=s[i+3];
            }
            if(i!=0&&i!=3&&i!=6)
            {
                s[i]^=s[i-1]^=s[i]^=s[i-1];
                ns=contor(s);
                if(!pre[ns])
                {
                    pre[ns]=x;
                    dir[ns]='l';
                    q[rear++]=ns;
                }
                s[i]^=s[i-1]^=s[i]^=s[i-1];
            }
            if(i!=2&&i!=5&&i!=8)
            {
                s[i]^=s[i+1]^=s[i]^=s[i+1];
                ns=contor(s);
                if(!pre[ns])
                {
                    pre[ns]=x;
                    dir[ns]='r';
                    q[rear++]=ns;
                }
                s[i]^=s[i+1]^=s[i]^=s[i+1];
            }
        }
        if(flag)
        {
            print(0);
            printf("\n");
        }
        else printf("unsolvable\n");
    }
    return 0;
}
posted @ 2012-04-20 20:17  'wind  阅读(183)  评论(0编辑  收藏  举报