八数码问题POJ1077

/*T T坑爹的八数码*/

#include<iostream>

#include<queue>

#include<utility>

#include<set>

#include<cstdio>

using namespace std;

#define maxn 300

char dir1[4]= {'u','d','l','r'};

char dir2[4]= {'d','u','r','l'};

char rr[maxn];

struct status_struct

{

    int steps;

    int data[9];

    int zero_pos;

    char road[maxn];

    status_struct(const char *str)

    {

        steps=0;

        for(int i=0; i<9; i++)

        {

            if(str[i]=='x')

            {

                zero_pos=i;

                data[i]=0;

            }

            else data[i]=str[i]-'0';

        }

    }

    bool operator==(const status_struct &ss) const

    {

        for(int i=0; i<9; i++)

        {

            if(data[i]!=ss.data[i])

                return false;

        }

        return true;

    }

    bool operator!=(const status_struct &ss) const

    {

        return !operator==(ss);

    }

    bool operator < (const status_struct &ss) const

    {

        for (int index = 0; index < 9; index++)

        {

            if (data[index] < ss.data[index])

            {

                return true;

            }

            else if (data[index] > ss.data[index])

            {

                return false;

            }

        }

        return false;

    }

    bool internal_move(int new_pos,bool inc,char cc)

    {

        data[zero_pos]=data[new_pos];

        data[new_pos]=0;

        zero_pos=new_pos;

        if(inc)

            road[steps++]=cc;

        else steps--;

        return true;

    }

    bool move(int direction,bool inc,char cc)

    {

        switch (direction)

        {

        case 0:

            if(zero_pos<3)

                return false;

            return internal_move(zero_pos-3,inc,cc);

        case 1:

            if(zero_pos>=6) return false;

            return internal_move(zero_pos+3,inc,cc);

        case 2:

            if(zero_pos%3==0) return false;

            return internal_move(zero_pos-1,inc,cc);

        case 3:

            if(zero_pos%3==2) return false;

            return internal_move(zero_pos+1,inc,cc);

        default:

            return false;

        }

    }

};

int find_path(const char * a,const char *b)

{

    queue<status_struct> q[2];

    set<status_struct> s[2];

    q[0].push(a);

    s[0].insert(a);

    q[1].push(b);

    s[1].insert(b);

    while(1)

    {

        for(int expand=0; expand<2; expand++)

        {

            status_struct ss=q[expand].front();

            q[expand].pop();

            set <status_struct>::iterator iter=s[!expand].find(ss);

            if(*iter==ss)

            {

                int temp=0;

                if(expand)

                {

                    for(int i=0; i<iter->steps; i++)

                        rr[temp++]=iter->road[i];

                    for(int i=ss.steps-1; i>=0; i--)

                        rr[temp++]=ss.road[i];

                }

                else

                {

                    for(int i=0; i<ss.steps; i++)

                        rr[temp++]=ss.road[i];

                    for(int i=iter->steps-1; i>=0; i--)

                        rr[temp++]=iter->road[i];

                }

                rr[temp]=0;

                return iter->steps+ss.steps;

            }

            char jess[4];

            for(int i=0; i<4; i++)

            {

                jess[i]=expand?dir2[i]:dir1[i];

            }

            for(int direction=0; direction<4; direction++)

            {

                if(ss.move(direction,true,jess[direction]))

                {

                    set<status_struct>::iterator iter=s[expand].find(ss);

                    if(*iter!=ss)

                    {

                        q[expand].push(ss);

                        s[expand].insert(ss);

                    }

                    ss.move(direction^1,false,jess[direction^1]);

                }

            }

        }

    }

}

bool cantuo(char *src)

{

    int sum=0;

    for(int i=0; i<9; i++)

    {

        if(src[i]=='x') continue;

        for(int j=i+1; j<9; j++)

        {

            if(src[j]=='x') continue;

            if(src[j]<src[i]) sum++;

        }

    }

    if(sum&1)

        return true;

    return false;

}

int main()

{

    char a[20];

    char src[20];

    gets(a);

    int j=0,i=0;

    while(a[i]!=0)

    {

        if(a[i]!=' ') src[j++]=a[i];

        i++;

    }

    src[j]=0;

    if(cantuo(src)) puts("unsolvable");

    else

    {

        find_path(src,"12345678x");

        printf("%s",rr);

    }

}

 

你可能感兴趣的:(poj)