hdu 1043 eight 八数码问题 bfs 和 A*

广搜+预处理 265MS 19436K

内存用的很大

#include<iostream>
#include<queue>

using namespace std;

const int MAX=362890;

struct eight
{
    int map[9];
    int zero;
    int id;
//    string route;
}now,next;

int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
char dir[4]={'u','d','l','r'};
int key[9]={1,1,2,6,24,120,720,5040,40320};
bool hash[MAX];
string route[MAX];

int num_to_hash(int *);
int bfs();
void show(int k);

int end;

int main()
{
    
    char c;
    int start[9];

    int temp;
    bfs();

    while(cin>>c)
    {
        int k=0;
        int i=0; 
        
        c=='x'?start[i]=0:start[i]=c-'0';  
        for(i=1;i<9;i++)  
            cin>>c,c=='x'?start[i]=0:start[i]=c-'0'; 

        temp=0;
        for(i=0;i<9;i++)
        {
            for(int j=i+1;j<9;j++)
            {
                if(start[i]>start[j])
                    temp++;
            }
        }
        end=num_to_hash(start);
        show(end);
    }

    return 0;
}

int num_to_hash(int *t)
{
    int sum=0,temp;
    for(int i=0;i<9;i++)
    {
        temp=0;
        for(int j=i+1;j<9;j++)
        {
            if(t[i]>t[j])
                temp++;    
        }
        sum+=temp*key[8-i];
    }
    return sum;
}

int bfs()
{
    queue<eight>q;
    int x,y,nx,ny;

    memset(hash,false,sizeof(hash));

    int temp;

    now.zero=8;
    for(int i=1;i<9;i++)
        now.map[i-1]=i;
    now.map[8]=0;

    now.id=num_to_hash(now.map);
    route[now.id]="";

    q.push(now);

    hash[now.id]=true;

    while(!q.empty())
    {
        now=q.front();
        q.pop();

        x=now.zero/3;
        y=now.zero%3;

        for(int i=0;i<4;i++)
        {
            nx=x+d[i][0];
            ny=y+d[i][1];

            if(nx<0 || nx>2 || ny<0 || ny>2)
                continue;

            next=now;

            temp=nx*3+ny;
            next.map[now.zero]=next.map[temp];
            next.map[temp]=0;
            next.zero=temp;

            temp=num_to_hash(next.map);
            

            
            next.id=temp;

            if(!hash[temp])
            {
                hash[temp]=true;
                route[temp]=route[now.id];
                route[temp]+=dir[i];

                q.push(next);
            }
        }
    }

    return 0;
}

void show(int t)
{
    if(!hash[t])
        cout<<"unsolvable";
    else
        for(int k=route[t].size()-1;k>=0;k--)
            cout<<route[t][k];
    cout<<endl;
}


A* +曼哈顿距离 625MS 752K

不用预处理625MS, 重点是752K内存,比广搜的零头还少

#include<iostream>
#include<queue>

using namespace std;

const int MAX=362890;

struct eight
{
    int map[9];
    int zero;
    int id;
    int realstep;
    int manhattan;
    bool operator < (const eight & e)const
    {
        int a,b;
        a=15*manhattan+realstep;
        b=15*e.manhattan+e.realstep;
        if(a!=b)
            return a>b;
        else
            return realstep>e.realstep;
    }
    string route;
}now,next;

int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
char dir[4]={'d','u','r','l'};
int key[9]={1,1,2,6,24,120,720,5040,40320};
bool hash[MAX];

int num_to_hash(int *);
int Manhattan(int *);
void show();
void bfs();
inline abs(int a);

string answer;

int main()
{
    
    char c;

    while(cin>>c)
    {
        int k=0;
        int i=0; 
        
        c=='x'? (now.map[i]=0,now.zero=i) : now.map[i]=c-'0'; 
        
        for(i=1;i<9;i++)  
            cin>>c,c=='x'? (now.map[i]=0,now.zero=i) : now.map[i]=c-'0';

        int temp=0;
        for(i=0;i<9;i++)
        {
            for(int j=i+1;j<9;j++)
            {
                if(now.map[i]>now.map[j] && now.map[i]!=0 && now.map[j]!=0)
                    temp++;
            }
        }  //逆序数对

        if(temp%2==1)
            cout<<"unsolvable"<<endl;
        else
        {
            now.id=num_to_hash(now.map);
            if(now.id==46233)
                cout<<endl;
            else
            {
                bfs();
                show();
            }
        }
    }
    

    return 0;
}

int num_to_hash(int *t)
{
    int sum=0,temp;
    for(int i=0;i<9;i++)
    {
        temp=0;
        for(int j=i+1;j<9;j++)
        {
            if(t[i]>t[j])
                temp++;    
        }
        sum+=temp*key[8-i];
    }
    return sum;
}

int Manhattan(int * t)
{
    int sum=0;
    for(int i=0;i<9;i++)
    {
        if(t[i]!=0)
        {
            sum+= abs((t[i]-1)/3-i/3) + abs((t[i]-1)%3-i%3);
        }
    }
    return sum;
}

void bfs()
{
    priority_queue<eight>q;
    int x,y,nx,ny;

    memset(hash,false,sizeof(hash));
    answer="";

    int temp;

    now.manhattan=Manhattan(now.map);
    now.realstep=0;
    now.route="";

    q.push(now);

    hash[now.id]=true;

    while(!q.empty())
    {
        now=q.top();
        q.pop();

        x=now.zero/3;
        y=now.zero%3;

        for(int i=0;i<4;i++)
        {
            nx=x+d[i][0];
            ny=y+d[i][1];

            if(nx<0 || nx>2 || ny<0 || ny>2)
                continue;

            next=now;

            temp=nx*3+ny;
            next.map[now.zero]=next.map[temp];
            next.map[temp]=0;
            next.zero=temp;
            next.realstep++;
//            if(next.realstep>50)
//                continue;
            
            temp=num_to_hash(next.map);
                
            if(!hash[temp])
            {
                
                next.manhattan=Manhattan(next.map);

                next.route+=dir[i];
                next.id=temp;
                hash[temp]=true;

                if(temp==46233)
                {
                    answer=next.route;
                    return ;
                }

                q.push(next);
            }
        }
    }
}

void show()
{
    if(!hash[46233])
        cout<<"unsolvable";
    else
        for(int k=0;k<answer.size();k++)
            cout<<answer[k];
    cout<<endl;
}

inline abs(int a)
{
    return a>0? a:-a;
}


你可能感兴趣的:(HDU)