hdu3095

Eleven puzzle

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


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.

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!
 

Source
 

Recommend
lcy



题意:
搜索题。双向bfs,求出起点状态到终点的最小步数。
思路:
双向bfs,每次拓展节点时,从两个空块开始拓展,然后使用一个long long数记录一下当前的状态。


#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragmp 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;
} p;

map<long long,int >mp[2];
queue<node>que;

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

typedef long long ll;
ll has(int a[][5])
{
    ll sum=0;
    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
        {
            if(a[i][j]==0x3f3f3f3f)
                continue;
            else
            {
                if(a[i][j]/10)
                    sum=sum*100+a[i][j];
                else
                    sum=sum*10+a[i][j];

            }
        }

    }
    return sum;
}

inline bool ok(int x1,int y1,node k)
{
    if(x1<0||x1>=5||y1<0||y1>=5)
        return 0;
    if(k.g[x1][y1]==12||k.g[x1][y1]==0x3f3f3f3f)
        return 0;
    else
        return 1;
}
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;
}



int dx[]= {0,0,-1,1};
int dy[]= {1,-1,0,0};


void bfs(int flag)
{
//    mp[flag].clear();
//    while(!que.empty())
//        que.pop();
//    mp[flag][has(p.g)]=1;
//    //printf("has:%lld\n",has(p.g));
//    que.push(p);

     mp[flag].clear();
    node k;
    while(!que.empty()) que.pop();
    que.push(p);
    mp[flag][has(p.g)]=1;
    while(!que.empty())
    {
      k=que.front();
        que.pop();
        long long pri=has(k.g);
        if(flag)
        {
            if(mp[0][pri])
            {
                if(k.step+mp[0][pri]-2<=20)
                {
                    printf("%d\n",k.step+mp[0][pri]-2);
                    return ;
                }
                else
                    continue;
            }
        }
        for(int i=0; i<4; i++)
        {
            node ne=k;
            int x,y;
            x=ne.x1=k.x1+dx[i];
            y=ne.y1=k.y1+dy[i];
            //printf("x1:%d  y1:%d   x:%d  y:%d\n",k.x1,k.y1,x,y);
            if(ok(x,y,k))             //!!!!!!!!!!!!!!!!!!!
            {ne.step++;
            if(flag==0&&ne.step>13)
                continue;
            if(flag&&ne.step>11)
                continue;
            swap(ne.g[ne.x1][ne.y1],ne.g[k.x1][k.y1]);
             ll ha=has(ne.g);
            if(mp[flag][ha])
                continue;
            mp[flag][ha]=ne.step;
            ne.x1=x;
            ne.y1=y;
            que.push(ne);
            }
        }
// for(int i=0; i<4; i++)
//        {
//          node ne=k;
//            int x,y;
//            x=ne.x1=k.x1+dir[i][0];
//            y=ne.y1=k.y1+dir[i][1];
//            //printf("x1:%d  y1:%d   x:%d  y:%d\n",k.x1,k.y1,x,y);
//            if(!ok(x,y,k))
//                continue;
//          
//            ne.step++;
//            if(flag==0&&ne.step>13)
//                continue;
//            if(flag&&ne.step>11)
//                continue;
//            swap(ne.g[x][y],ne.g[k.x1][k.y1]);
//             ll ha=has(ne.g);
//            if(mp[flag][ha])
//                continue;
//            mp[flag][ha]=ne.step;
//            ne.x1=x;
//            ne.y1=y;
//            que.push(ne);
//        }

        for(int i=0; i<4; i++)
        {
            int x,y;
            x=k.x2+dx[i];
            y=k.y2+dy[i];
            if(ok(x,y,k))
           //     continue;
            {node ne=k;
            ne.step++;
            swap(ne.g[x][y],ne.g[k.x2][k.y2]);
            if(flag&&ne.step>10)
                continue;
            if(!flag&&ne.step>12)
                continue;
             ll tmp=has(ne.g);
            if(mp[flag][tmp])
                continue;
            ne.x2=x;
            ne.y2=y;
            mp[flag][tmp]=ne.step;
            que.push(ne);
            }
        }
    }
    if(flag)
        puts("No solution!");
}

void bfsx(int flag)
{
    mp[flag].clear();
    node k;
    while(!que.empty()) que.pop();
    que.push(p);
    mp[flag][has(p.g)]=1;
    while(!que.empty())
    {
        k=que.front();
        que.pop();
        long long pri=has(k.g);
         if(flag)
        {
            if(mp[0][pri])
            {
                if(k.step+mp[0][pri]-2<=20)
                {
                    printf("%d\n",k.step+mp[0][pri]-2);
                    return ;
                }
                else
                    continue;
            }
        }

         for(int i=0; i<4; i++)
        {
          node ne=k;
            int x,y;
            x=ne.x1=k.x1+dir[i][0];
            y=ne.y1=k.y1+dir[i][1];
            //printf("x1:%d  y1:%d   x:%d  y:%d\n",k.x1,k.y1,x,y);
            if(!ok(x,y,k))
                continue;
          //  puts("okkkk");
            ne.step++;
            if(flag==0&&ne.step>13)
                continue;
            if(flag&&ne.step>11)
                continue;
            swap(ne.g[x][y],ne.g[k.x1][k.y1]);
             ll ha=has(ne.g);
            if(mp[flag][ha])
                continue;
            mp[flag][ha]=ne.step;
            ne.x1=x;
            ne.y1=y;
            que.push(ne);
        }

             for(int i=0; i<4; i++)
        {
            int x,y;
            x=k.x2+dir[i][0];
            y=k.y2+dir[i][1];
            if(!ok(x,y,k))
                continue;
      node ne=k;
            ne.step++;
            if(flag&&ne.step>11)
                continue;
            if(!flag&&ne.step>13)
                continue;
            swap(ne.g[x][y],ne.g[k.x2][k.y2]);
            ll tmp=has(ne.g);
            if(mp[flag][tmp])
                continue;
            ne.x2=x;
            ne.y2=y;
            mp[flag][tmp]=ne.step;
            que.push(ne);
        }


    }
    if(flag) printf("No solution!\n");
}

int main()
{
    memset(p.g,0x3f3f3f3f,sizeof p.g);
    p.g[0][2]=12;
    p.g[1][1]=1;
    p.g[1][2]=2;
    p.g[1][3]=3;
    p.g[2][0]=4;
    p.g[2][1]=5;
    p.g[2][2]=6;
    p.g[2][3]=7;
    p.g[2][4]=8;
    p.g[3][1]=9;
    p.g[3][2]=10;
    p.g[3][3]=11;
    p.g[4][2]=12;
    p.x1=0;
    p.y1=2;
    p.x2=4;
    p.y2=2;
    p.step=1;

    bfs(0);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(p.g,0x3f3f3f3f,sizeof p.g);
        p.step=1;
        int swi=0;
        for(int i=0; i<5; i++)
        {
            if(i==0||i==4)
            {
                scanf("%d",&p.g[i][2]);
                int j=2;
                if(p.g[i][j]==0)
                {
                    p.g[i][j]=12;
                    if(swi)
                    {
                        p.x1=i;
                        p.y1=j;
                    }
                    else
                    {
                        p.x2=i;
                        p.y2=j;
                    }
                    swi=1;
                }
            }
            else if(i==1||i==3)
                for(int j=1; j<=3; j++)
                {
                    scanf("%d",&p.g[i][j]);
                    if(p.g[i][j]==0)
                    {
                        p.g[i][j]=12;
                        if(swi)
                        {
                            p.x1=i;
                            p.y1=j;
                        }
                        else
                        {
                            p.x2=i;
                            p.y2=j;
                        }
                        swi=1;
                    }
                }
            else
                for(int j=0; j<5; j++)
                {
                    scanf("%d",&p.g[i][j]);
                    if(p.g[i][j]==0)
                    {
                        p.g[i][j]=12;
                        if(swi)
                        {
                            p.x1=i;
                            p.y1=j;
                        }
                        else
                        {
                            p.x2=i;
                            p.y2=j;
                        }
                        swi=1;
                    }
                }
        }
        bfs(1);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值