HDU 3095 Eleven puzzle(双向广度优先搜索)

Eleven puzzle

Time Limit: 20000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 531    Accepted Submission(s): 135



Problem Description
Partychen invents a new game named “Eleven Puzzle” .Just like the classic game “Eight Puzzle”,but there some difference between them:The shape of the board is different and there are two empty tiles.
HDU 3095 Eleven puzzle(双向广度优先搜索)_第1张图片

The tile in black means it’s empty

Each step you can move only one tile.
Here comes the problem.How many steps at least it required to done the game.
 

Input
The first line of input contains one integer specifying the number of test cases to follow.
Every case contains five lines to describe the initial status of the board. 0 means empty.

It’s confirmed that the board is legal.
 

Output
Output one line for each testcase.Contain an integer denotes the minimum step(s) it need to complete the game.Or “No solution!” if it’s impossible to complete the game within 20 steps.
 

Sample Input
 
   
3 2 1 0 3 4 5 6 7 8 9 0 11 10 0 1 2 3 4 5 6 7 8 9 10 11 0 0 11 10 9 8 7 6 5 4 3 2 1 0
 

Sample Output
 
   
2 0 No solution!
 
题意:
给出一个如图的图形,要求用最小的步数变化成右图图形

分析:
如果单向搜索,无论是从终状态还是从开始状态都会直接超时,计算次数为4^20 > 10^8
那么此时应该考虑双向搜索,即队列中同时保存终状态的状态转移和开始状态的状态转移,每一种状态bfs10步,当两端相撞时得到结果,计算次数 4^10

我用的map做状态映射,效果并不差 156ms

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f

long long d[30];
int g[5][5];

struct node
{
    int g[5][5];
    int step;
    int x1,y1;
    int x2,y2;
} p1;

mapmp[2];
queueque;

int dir[][5]= {{0,1},{0,-1},{1,0},{-1,0}};

bool inbound(node k,int x,int y)
{
    if(x>=0&&x<5&&y>=0&&y<5)
    {
        if(k.g[x][y]==INF||k.g[x][y]==12) return false;
        else return true;
        return false;
    }
    return false;
}

long long getval(node k)
{
    long long sum=0;
    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
        {
            if(k.g[i][j]!=INF)
            {
                if(k.g[i][j]/10) sum=sum*100+k.g[i][j];
                else sum=sum*10+k.g[i][j];
            }
        }
    }
    return sum;
}

void bfsx(int flag)
{
    mp[flag].clear();
    node k;
    while(!que.empty()) que.pop();
    que.push(p1);
    mp[flag][getval(p1)]=1;
    while(!que.empty())
    {
        k=que.front();
        que.pop();
        long long pri=getval(k);
        if(flag)
        {
            if(mp[0][pri])
            {
                if(mp[0][pri]+k.step-2<=20)
                {
                    printf("%d\n",mp[0][pri]+k.step-2);
                    return ;
                }
                else continue;
            }
        }
        for(int i=0; i<4; i++)
        {
            node temp=k;
            int s=temp.x1+dir[i][0];
            int t=temp.y1+dir[i][1];
            if(inbound(temp,s,t))
            {
                temp.step++;
                if(temp.step>12&&!flag) continue;
                else if(temp.step>10&&flag) continue;
                swap(temp.g[temp.x1][temp.y1],temp.g[s][t]);
                long long pri=getval(temp);
                if(mp[flag][pri]) continue;
                mp[flag][pri]=temp.step;
                temp.x1=s,temp.y1=t;
                que.push(temp);
            }
        }
        for(int i=0; i<4; i++)
        {
            node temp=k;
            int s=temp.x2+dir[i][0];
            int t=temp.y2+dir[i][1];
            if(inbound(temp,s,t))
            {
                temp.step++;
                if(temp.step>12&&!flag) continue;
                else if(temp.step>10&&flag) continue;
                swap(temp.g[temp.x2][temp.y2],temp.g[s][t]);
                long long pri=getval(temp);
                if(mp[flag][pri]) continue;
                mp[flag][pri]=temp.step;
                temp.x2=s,temp.y2=t;
                que.push(temp);
            }
        }
    }
    if(flag) printf("No solution!\n");
}

int main()
{
    memset(g,0x3f,sizeof g);
    g[0][2]=12;
    g[1][1]=1,g[1][2]=2,g[1][3]=3;
    g[2][0]=4,g[2][1]=5,g[2][2]=6,g[2][3]=7,g[2][4]=8;
    g[3][1]=9,g[3][2]=10,g[3][3]=11;
    g[4][2]=12;
    memcpy(p1.g,g,sizeof g);
    p1.x1=0,p1.y1=2;
    p1.x2=4,p1.y2=2;
    p1.step=1;
    bfsx(0);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(g,0x3f,sizeof g);
        for(int i=0; i<5; i++)
        {
            if(i==0||i==4) scanf("%d",&g[i][2]);
            else if(i==1||i==3) for(int j=1; j<=3; j++) scanf("%d",&g[i][j]);
            else for(int j=0; j<5; j++) scanf("%d",&g[i][j]);
        }
        int flag=0;
        for(int i=0; i<5; i++)
        {
            for(int j=0; j<5; j++)
            {
                if(g[i][j]==0)
                {
                    g[i][j]=12;
                    if(!flag) p1.x1=i,p1.y1=j;
                    else p1.x2=i,p1.y2=j;
                    flag=1;
                }
            }
        }
        memcpy(p1.g,g,sizeof g);
        p1.step=1;
        bfsx(1);
    }
    return 0;
}




你可能感兴趣的:(===搜索===)