HDU 1043 八数码问题【双向BFS】

HDU 1043 八数码问题【双向BFS】

题目链接
题意:给你一个初始状态,问你能否移动到最终的完成状态,如果能输出任意一组解,否则输出unsolved。
思路:乍一看是个BFS,但是状态过多会TLE或者MLE,但是除可BFS确实没得写了,这时候就要用到双向BFS了,起点终点同时BFS,判断相遇,路径用string+就行了。
注意点:正向路径s=s+c,逆向s=c+s;输出也要注意先输出正向;
剪枝的话就判断逆序数就行了;
在这里插入图片描述

#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
char s[125];
map<int,string>vis1,vis2;
map<int,char>mp;
map<int,char>mpp;
int st=0,ed=123456780,dx,dy,mat[4][4],ans=-1,flag;
int dir[4][2]= {{0,1},{0,-1},{-1,0},{1,0}};
struct node
{
    int now;
    string s;
};
void fun(int ok)
{
    mat[1][1]=0;
    dx=1,dy=1;
    int j=3,i=3;
    while(ok)
    {
        mat[i][j]=ok%10;
        ok/=10;
        if(!mat[i][j])
            dx=i,dy=j;
        j--;
        if(j==0)
            i--,j=3;
    }
}
int tran()
{
    int ans=0;
    for(int i=1; i<=3; i++)
    {
        for(int j=1; j<=3; j++)
            ans=ans*10+mat[i][j];
    }
    return ans;
}
int Tbfs()
{
    mp[0]='r',mp[1]='l',mp[2]='u',mp[3]='d';
    mpp[0]='l',mpp[1]='r',mpp[2]='d',mpp[3]='u';
    queue<node>q1,q2;
    node f;
    q1.push({st,""}),q2.push({ed,""});
    vis1[st]=1,vis2[ed]=1;
    while(!q1.empty()&&!q2.empty())
    {
        if(q1.size()<q2.size())
            f=q1.front(),q1.pop(),flag=1;
        else
            f=q2.front(),q2.pop(),flag=0;
        fun(f.now);
        for(int i=0; i<4; i++)
        {
            char c=mp[i];
            char cc=mpp[i];
            int xx=dir[i][0]+dx;
            int yy=dir[i][1]+dy;
            if(xx<1||xx>3||yy<1||yy>3)
                continue;
            swap(mat[xx][yy],mat[dx][dy]);
            int no=tran();
            swap(mat[xx][yy],mat[dx][dy]);
            if(flag==1)///q1
            {
                if(vis1[no].size())
                    continue;
                if(vis2[no].size())
                {
                    cout<<f.s;
                    cout<<c;
                    cout<<vis2[no]<<endl;
                    return 1;
                }
                vis1[no]=f.s+c;
                q1.push({no,f.s+c});
            }
            else
            {
                if(vis2[no].size())
                    continue;
                if(vis1[no].size())
                {
                    cout<<vis1[no];
                    cout<<cc;
                    cout<<f.s<<endl;
                    return 1;
                }
                vis2[no]=cc+f.s;
                q2.push({no,cc+f.s});
            }
        }
    }
    return -1;
}
int main()
{
    char c;
    while(gets(s))
    {
        st=0;
        ed=123456780;
        vis1.clear(),vis2.clear();
        int len=strlen(s);
        int a[10],cnt=0;
        for(int i=0; i<len; i++)
        {
            char c=s[i];
            if(c==' ')continue;
            else if(c=='x')
                st=st*10;
            else
            {
                st=st*10+(c-'0');
                a[++cnt]=c-'0';
            }
        }
        int k=0;
        for(int i=1; i<=8; i++)
        {
            for(int j=i+1; j<=8; j++)
            {
                if(a[i]>a[j])
                    k++;
            }
        }

        if(k&1)
        {
            printf("unsolvable\n");
            continue;
        }
        ans=Tbfs();
        if(ans==-1)
            printf("unsolvable\n");

    }
}

你可能感兴趣的:(双向BFS)