zoukankan      html  css  js  c++  java
  • (中等) HDU 1043 Eight,经典搜索问题。

      Problem Description
      The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as:

    1 2 3 4
    5 6 7 8
    9 10 11 12
    13 14 15 x

      where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:

    1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
    5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
    9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
    13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
    r-> d-> r->

      The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively.

      Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
    frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course).

      In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
    arrangement.

      这前那篇文章也介绍了一些了,那位大神的文章也写的很好了,我就是来水一下。

      首先就是我写的康托展开,用来表示每一个状态,其实对于一个状态 2 3 4 1 5 x 7 6 8来说,把x当作0,就是0到8的一个全排了,那么一共就9!种,这样就是第一个*8!,第二个*7!。。。这样下去。。。不过每一个乘的数应该是这个数本身的值减去前面比他小的个数,也就是他在剩下的数里面是第几个。

      由一个值转化为一个排列也是如此,每一次找第k个还没有用到的数,就是那个数了。因为这里就只有9个数,直接n^2过一遍就好了。。。(对于很多数,可以用数状数组来做,转化为排列的话就是二分加数状数组。)

      然后是减枝,减去无解的情况。对于每一次移动,数的逆序对的奇偶性是不会改变的(这里x不算数),然后的话先求逆序数,如果为奇就直接pass掉。

    首先是第一次写,

    BFS+康托+剪枝,TLE了。

    #include<iostream>
    #include<cstring>
    
    using namespace std;
    
    const int maxn=400005;
    const int Enum=46233;
    const int jie[9]={1,1,2,6,24,120,720,5040,40320};
    
    int que[400005];
    int fa[maxn];
    int las,fir;
    int rem[maxn];
    char ans1[maxn];
    int cou;
    
    int hebing(int (*m)[3])
    {
        bool vis[10]={0};
        int cou;
        int ans=0;
    
        for(int i=0;i<9;++i)
        {
            cou=0;
            for(int j=0;j<m[i/3][i%3];++j)
                if(vis[j])
                    ++cou;
    
            vis[m[i/3][i%3]]=1;
    
            ans+=(m[i/3][i%3]-cou)*jie[8-i];
        }
    
        return ans;
    }
    
    void zhankai(int (*m)[3],int x)
    {
        bool vis[10]={0};
        int cou;
        int k;
    
        for(int i=0;i<3;++i)
            for(int j=0;j<3;++j)
            {
                cou=x/jie[8-3*i-j]+1;        //    !!!
                x%=jie[8-3*i-j];
                
                for(k=0;k<9&&cou;++k)
                    if(vis[k]==0)
                        --cou;
    
                vis[k-1]=1;                    //  !!!
                m[i][j]=k-1;                //  !!!
            }
    }
    
    void swap(int &a,int &b)
    {
        int temp=a;
        a=b;
        b=temp;
    }
    
    bool judge(int x,int y)
    {
        if(x<0||y<0||x>2||y>2)
            return 0;
    
        return 1;
    }
    
    void showans()
    {
        int temp=Enum;
        char c;
        cou=0;
    
        while(fa[temp]!=-1)
        {
            if(rem[temp]==1)
                c='d';
            else if(rem[temp]==2)
                c='l';
            else if(rem[temp]==3)
                c='u';
            else
                c='r';
    
            ans1[cou++]=c;
    
            temp=fa[temp];
        }
    
        for(int i=cou-1;i>=0;--i)
            cout<<ans1[i];
    
        cout<<endl;
    }
    
    void solve(int (*m)[3])
    {
        int ni=0;
    
        for(int i=0;i<9;++i)
            for(int j=0;j<i;++j)
                if(m[i/3][i%3]&&m[j/3][j%3])
                    if(m[i/3][i%3]<m[j/3][j%3])
                        ++ni;
    
        if(ni%2)
        {
            cout<<"unsolvable
    ";
            return;
        }
    
        las=fir=0;
        memset(rem,0,sizeof(rem));
    
        bool ok=0;
        int temp,t1[3][3],temp1;
        int x0,y0;
    
        temp=hebing(m);
    
        rem[temp]=-1;
        que[las++]=temp;
        fa[temp]=-1;
    
        while(las-fir)
        {
            temp=que[fir++];
    
            if(temp==Enum)
            {
                ok=1;
                break;
            }
    
            zhankai(t1,temp);
    
            for(int i=0;i<3;++i)
                for(int j=0;j<3;++j)
                    if(t1[i][j]==0)
                        x0=i,y0=j;
    
            if(judge(x0-1,y0))
            {
                swap(t1[x0][y0],t1[x0-1][y0]);
                temp1=hebing(t1);
    
                if(rem[temp1]==0)
                {
                    rem[temp1]=3;
                    fa[temp1]=temp;
                    que[las++]=temp1;
                }
    
                swap(t1[x0][y0],t1[x0-1][y0]);
            }
            if(judge(x0+1,y0))
            {
                swap(t1[x0+1][y0],t1[x0][y0]);
                temp1=hebing(t1);
    
                if(rem[temp1]==0)
                {
                    rem[temp1]=1;
                    fa[temp1]=temp;
                    que[las++]=temp1;
                }
    
                swap(t1[x0][y0],t1[x0+1][y0]);
            }
            if(judge(x0,y0-1))
            {
                swap(t1[x0][y0-1],t1[x0][y0]);
                temp1=hebing(t1);
    
                if(rem[temp1]==0)
                {
                    rem[temp1]=2;
                    fa[temp1]=temp;
                    que[las++]=temp1;
                }
    
                swap(t1[x0][y0],t1[x0][y0-1]);
            }
            if(judge(x0,y0+1))
            {
                swap(t1[x0][y0+1],t1[x0][y0]);
                temp1=hebing(t1);
    
                if(rem[temp1]==0)
                {
                    rem[temp1]=4;
                    fa[temp1]=temp;
                    que[las++]=temp1;
                }
    
                swap(t1[x0][y0],t1[x0][y0+1]);
            }
        }
    
        if(ok)
            showans();
        else
            cout<<"unsolvable"<<endl;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
    
        int m[3][3];
        char c;
    
        while(cin>>c)
        {
            m[0][0]=c=='x'?0:c-'0';
            cin>>c;
            m[0][1]=c=='x'?0:c-'0';
            cin>>c;
            m[0][2]=c=='x'?0:c-'0';
    
            for(int i=1;i<3;++i)
                for(int j=0;j<3;++j)
                {
                    cin>>c;
                    m[i][j]=c=='x'?0:c-'0';
                }
    
            solve(m);
        }
    
        return 0;
    }
    View Code

    然后就是

    双向BFS+康托+剪枝,就过了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    const int maxn=400005;
    const int Enum=46233;
    const int jie[9]={1,1,2,6,24,120,720,5040,40320};
    const int step[4][2]={{1,0},{0,-1},{-1,0},{0,1}};
    
    int Snum,Mnum;
    int fa[maxn],son[maxn];
    int rem[maxn],Mrem;
    int que1[maxn],que2[maxn];
    int las1,las2,fir1,fir2;
    char ans[maxn];
    
    int hebing(int (*m)[3])
    {
        bool vis[10]={0};
        int cou;
        int ans=0;
    
        for(int i=0;i<9;++i)
        {
            cou=0;
            for(int j=0;j<m[i/3][i%3];++j)
                if(vis[j])
                    ++cou;
    
            vis[m[i/3][i%3]]=1;
    
            ans+=(m[i/3][i%3]-cou)*jie[8-i];
        }
    
        return ans;
    }
    
    void zhankai(int (*m)[3],int x)
    {
        bool vis[10]={0};
        int cou;
        int k;
    
        for(int i=0;i<3;++i)
            for(int j=0;j<3;++j)
            {
                cou=x/jie[8-3*i-j]+1;        //    !!!
                x%=jie[8-3*i-j];
                
                for(k=0;k<9&&cou;++k)
                    if(vis[k]==0)
                        --cou;
    
                vis[k-1]=1;                    //  !!!
                m[i][j]=k-1;                //  !!!
            }
    }
    
    void swap(int &a,int &b)
    {
        int temp=a;
        a=b;
        b=temp;
    }
    
    bool judge(int x,int y)
    {
        if(x<0||y<0||x>2||y>2)
            return 0;
    
        return 1;
    }
    
    void showans()
    {
        int cou=0;
        char c;
        int tnum=Mnum;
    
        while(tnum!=Snum)
        {
            if(rem[tnum]==1)
                c='d';
            else if(rem[tnum]==2)
                c='l';
            else if(rem[tnum]==3)
                c='u';
            else
                c='r';
    
            ans[cou++]=c;
    
            tnum=fa[tnum];
        }
    
        for(int i=cou-1;i>=0;--i)
            cout<<ans[i];
    
        rem[Mnum]=Mrem;
        tnum=Mnum;
    
        while(tnum!=Enum)
        {
            rem[tnum]=-rem[tnum];
            if(rem[tnum]==1)
                c='u';
            else if(rem[tnum]==2)
                c='r';
            else if(rem[tnum]==3)
                c='d';
            else
                c='l';
    
            cout<<c;
    
            tnum=son[tnum];
        }
    
        cout<<endl;
    }
    
    bool bfs()
    {
        fir1=fir2=las1=las2=0;
    
        int temp,t1[3][3],t2[3][3];
        int tnum1,tnum2;
        int x01,y01,x02,y02;
    
        que1[las1++]=Snum;
        que2[las2++]=Enum;
    
        rem[Snum]=100;
        rem[Enum]=-100;
    
        son[Enum]=Enum;
        fa[Snum]=Snum;
    
        while(las1-fir1&&las2-fir2)
        {
            tnum1=que1[fir1++];
            tnum2=que2[fir2++];
    
            zhankai(t1,tnum1);
            zhankai(t2,tnum2);
    
            for(int i=0;i<3;++i)
                for(int j=0;j<3;++j)
                {
                    if(t1[i][j]==0)
                        x01=i,y01=j;
                    if(t2[i][j]==0)
                        x02=i,y02=j;
                }
    
            for(int i=0;i<4;++i)
            {
                if(judge(x01+step[i][0],y01+step[i][1])==0)
                    continue;
                
                swap(t1[x01][y01],t1[x01+step[i][0]][y01+step[i][1]]);
                temp=hebing(t1);
    
                if(rem[temp]==0)
                {
                    rem[temp]=i+1;
                    fa[temp]=tnum1;
                    que1[las1++]=temp;
                }
                else if(rem[temp]<0)
                {
                    fa[temp]=tnum1;
                    Mrem=rem[temp];
                    rem[temp]=i+1;
                    Mnum=temp;
    
                    return 1;
                }
    
                swap(t1[x01][y01],t1[x01+step[i][0]][y01+step[i][1]]);
            }
    
            for(int i=0;i<4;++i)
            {
                if(judge(x02+step[i][0],y02+step[i][1])==0)
                    continue;
    
                swap(t2[x02][y02],t2[x02+step[i][0]][y02+step[i][1]]);
                temp=hebing(t2);
    
                if(rem[temp]==0)
                {
                    rem[temp]=-(i+1);
                    son[temp]=tnum2;
                    que2[las2++]=temp;
                }
                else if(rem[temp]>0)
                {
                    son[temp]=tnum2;
                    Mrem=-(i+1);
                    Mnum=temp;
    
                    return 1;
                }
    
                swap(t2[x02][y02],t2[x02+step[i][0]][y02+step[i][1]]);
            }
        }
    
        return 0;
    }
    
    void solve(int (*m)[3])
    {
        int ni=0;
    
        for(int i=0;i<9;++i)
            for(int j=0;j<i;++j)
                if(m[i/3][i%3]&&m[j/3][j%3])
                    if(m[i/3][i%3]<m[j/3][j%3])
                        ++ni;
    
        if(ni%2)
        {
            cout<<"unsolvable
    ";
            return;
        }
    
        memset(rem,0,sizeof(rem));
    
        Snum=hebing(m);
    
        if(Snum==Enum)
        {
            cout<<endl;
            return;
        }
    
        if(bfs())
            showans();
        else
            cout<<"unsolvable
    ";
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
    
        int m[3][3];
        char c;
    
        while(cin>>c)
        {
            m[0][0]=c=='x'?0:c-'0';
            cin>>c;
            m[0][1]=c=='x'?0:c-'0';
            cin>>c;
            m[0][2]=c=='x'?0:c-'0';
    
            for(int i=1;i<3;++i)
                for(int j=0;j<3;++j)
                {
                    cin>>c;
                    m[i][j]=c=='x'?0:c-'0';
                }
    
            solve(m);
        }
    
        return 0;
    }
    View Code

    A*(曼哈顿距离)+康托+剪枝。

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<utility>
    #include<cmath>
    #include<cstdio>
    
    using namespace std;
    
    const int maxn=400005;
    const int Enum=46233;
    const int jie[9]={1,1,2,6,24,120,720,5040,40320};
    
    struct state
    {
        int F,G,num;
    
        state() {}
        state(int a,int b,int c):F(a),G(b),num(c) {}
    
        friend bool operator < (state x,state y)
        {
            return x.F>y.F;
        }
    };
    
    int fa[maxn];
    int rem[maxn];
    char ans1[maxn];
    int cou;
    
    int hebing(int (*m)[3])
    {
        bool vis[10]={0};
        int cou;
        int ans=0;
    
        for(int i=0;i<9;++i)
        {
            cou=0;
            for(int j=0;j<m[i/3][i%3];++j)
                if(vis[j])
                    ++cou;
    
            vis[m[i/3][i%3]]=1;
    
            ans+=(m[i/3][i%3]-cou)*jie[8-i];
        }
    
        return ans;
    }
    
    void zhankai(int (*m)[3],int x)
    {
        bool vis[10]={0};
        int cou;
        int k;
    
        for(int i=0;i<3;++i)
            for(int j=0;j<3;++j)
            {
                cou=x/jie[8-3*i-j]+1;        //    !!!
                x%=jie[8-3*i-j];
                
                for(k=0;k<9&&cou;++k)
                    if(vis[k]==0)
                        --cou;
    
                vis[k-1]=1;                    //  !!!
                m[i][j]=k-1;                //  !!!
            }
    }
    
    void swap(int &a,int &b)
    {
        int temp=a;
        a=b;
        b=temp;
    }
    
    bool judge(int x,int y)
    {
        if(x<0||y<0||x>2||y>2)
            return 0;
    
        return 1;
    }
    
    void showans()
    {
        int temp=Enum;
        char c;
        cou=0;
    
        while(fa[temp]!=-1)
        {
            if(rem[temp]==1)
                c='d';
            else if(rem[temp]==2)
                c='l';
            else if(rem[temp]==3)
                c='u';
            else
                c='r';
    
            ans1[cou++]=c;
    
            temp=fa[temp];
        }
    
        for(int i=cou-1;i>=0;--i)
            cout<<ans1[i];
    
        cout<<endl;
    }
    
    int getH(int (*m)[3])
    {
        int H=0;
    
        for(int i=0;i<3;++i)
            for(int j=0;j<3;++j)
                if(m[i][j])
                    H+=abs(i-(m[i][j]-1)/3)+abs(j-(m[i][j]-1)%3);
                else
                    H+=abs(i-2)+abs(j-2);
    
        return H;
    }
    
    void solve(int (*m)[3])
    {
        int ni=0;
    
        for(int i=0;i<9;++i)
            for(int j=0;j<i;++j)
                if(m[i/3][i%3]&&m[j/3][j%3])
                    if(m[i/3][i%3]<m[j/3][j%3])
                        ++ni;
    
        if(ni%2)
        {
            cout<<"unsolvable
    ";
            return;
        }
    
        priority_queue <state> que;
    
        memset(rem,0,sizeof(rem));
    
        bool ok=0;
        int temp,t1[3][3],temp1;
        int x0,y0;
        int H=0,G;
        state tsta;
    
        temp=hebing(m);
    
        que.push(state(H,0,temp));
        rem[temp]=-1;
        fa[temp]=-1;
    
        while(!que.empty())
        {
            H=0;
    
            tsta=que.top();
            que.pop();
    
            G=tsta.G;
            temp=tsta.num;
    
            if(temp==Enum)
            {
                ok=1;
                break;
            }
    
            zhankai(t1,temp);
    
            for(int i=0;i<3;++i)
                for(int j=0;j<3;++j)
                    if(t1[i][j]==0)
                        x0=i,y0=j;
    
            if(judge(x0-1,y0))
            {
                swap(t1[x0][y0],t1[x0-1][y0]);
                temp1=hebing(t1);
    
                if(rem[temp1]==0)
                {
                    H=getH(t1);
                    rem[temp1]=3;
                    fa[temp1]=temp;
                    que.push(state(G+1+H,G+1,temp1));
                }
    
                swap(t1[x0][y0],t1[x0-1][y0]);
            }
            if(judge(x0+1,y0))
            {
                swap(t1[x0+1][y0],t1[x0][y0]);
                temp1=hebing(t1);
    
                if(rem[temp1]==0)
                {
                    H=getH(t1);
                    rem[temp1]=1;
                    fa[temp1]=temp;
                    que.push(state(G+H+1,G+1,temp1));
                }
    
                swap(t1[x0][y0],t1[x0+1][y0]);
            }
            if(judge(x0,y0-1))
            {
                swap(t1[x0][y0-1],t1[x0][y0]);
                temp1=hebing(t1);
    
                if(rem[temp1]==0)
                {
                    H=getH(t1);
                    rem[temp1]=2;
                    fa[temp1]=temp;
                    que.push(state(G+H+1,G+1,temp1));
                }
    
                swap(t1[x0][y0],t1[x0][y0-1]);
            }
            if(judge(x0,y0+1))
            {
                swap(t1[x0][y0+1],t1[x0][y0]);
                temp1=hebing(t1);
    
                if(rem[temp1]==0)
                {
                    H=getH(t1);
                    rem[temp1]=4;
                    fa[temp1]=temp;
                    que.push(state(G+H+1,G+1,temp1));
                }
    
                swap(t1[x0][y0],t1[x0][y0+1]);
            }
        }
    
        if(ok)
            showans();
        else
            cout<<"unsolvable"<<endl;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
    
        int m[3][3];
        char c;
    
        while(cin>>c)
        {
            m[0][0]=c=='x'?0:c-'0';
            cin>>c;
            m[0][1]=c=='x'?0:c-'0';
            cin>>c;
            m[0][2]=c=='x'?0:c-'0';
    
            for(int i=1;i<3;++i)
                for(int j=0;j<3;++j)
                {
                    cin>>c;
                    m[i][j]=c=='x'?0:c-'0';
                }
    
            solve(m);
        }
    
        return 0;
    }
    View Code

    双向A*(曼哈顿距离)+康托+剪枝。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cmath>
    
    using namespace std;
    
    const int maxn=400005;
    const int Enum=46233;
    const int jie[9]={1,1,2,6,24,120,720,5040,40320};
    const int step[4][2]={{1,0},{0,-1},{-1,0},{0,1}};
    
    struct state
    {
        int F,G,num;
    
        state() {}
        state(int a,int b,int c):F(a),G(b),num(c) {}
    
        friend bool operator < (state x,state y)
        {
            return x.F>y.F;
        }
    };
    
    int Snum,Mnum;
    int fa[maxn],son[maxn];
    int rem[maxn],Mrem;
    char ans[maxn];
    
    int hebing(int (*m)[3])
    {
        bool vis[10]={0};
        int cou;
        int ans=0;
    
        for(int i=0;i<9;++i)
        {
            cou=0;
            for(int j=0;j<m[i/3][i%3];++j)
                if(vis[j])
                    ++cou;
    
            vis[m[i/3][i%3]]=1;
    
            ans+=(m[i/3][i%3]-cou)*jie[8-i];
        }
    
        return ans;
    }
    
    void zhankai(int (*m)[3],int x)
    {
        bool vis[10]={0};
        int cou;
        int k;
    
        for(int i=0;i<3;++i)
            for(int j=0;j<3;++j)
            {
                cou=x/jie[8-3*i-j]+1;        //    !!!
                x%=jie[8-3*i-j];
                
                for(k=0;k<9&&cou;++k)
                    if(vis[k]==0)
                        --cou;
    
                vis[k-1]=1;                    //  !!!
                m[i][j]=k-1;                //  !!!
            }
    }
    
    void swap(int &a,int &b)
    {
        int temp=a;
        a=b;
        b=temp;
    }
    
    bool judge(int x,int y)
    {
        if(x<0||y<0||x>2||y>2)
            return 0;
    
        return 1;
    }
    
    void showans()
    {
        int cou=0;
        char c;
        int tnum=Mnum;
    
        while(tnum!=Snum)
        {
            if(rem[tnum]==1)
                c='d';
            else if(rem[tnum]==2)
                c='l';
            else if(rem[tnum]==3)
                c='u';
            else
                c='r';
    
            ans[cou++]=c;
    
            tnum=fa[tnum];
        }
    
        for(int i=cou-1;i>=0;--i)
            cout<<ans[i];
    
        rem[Mnum]=Mrem;
        tnum=Mnum;
    
        while(tnum!=Enum)
        {
            rem[tnum]=-rem[tnum];
            if(rem[tnum]==1)
                c='u';
            else if(rem[tnum]==2)
                c='r';
            else if(rem[tnum]==3)
                c='d';
            else
                c='l';
    
            cout<<c;
    
            tnum=son[tnum];
        }
    
        cout<<endl;
    }
    
    int getH(int (*m)[3])
    {
        int H=0;
    
        for(int i=0;i<3;++i)
            for(int j=0;j<3;++j)
                if(m[i][j])
                    H+=abs(i-(m[i][j]-1)/3)+abs(j-(m[i][j]-1)%3);
                else
                    H+=abs(i-2)+abs(j-2);
    
        return H;
    }
    
    bool bfs()
    {
        priority_queue <state> que1,que2;
    
        int temp,t1[3][3],t2[3][3];
        int tnum1,tnum2;
        int x01,y01,x02,y02;
    
        state tsta1,tsta2;
        int H,G1,G2;
    
        que1.push(state(0,0,Snum));
        que2.push(state(0,0,Enum));
    
        rem[Snum]=100;
        rem[Enum]=-100;
    
        son[Enum]=Enum;
        fa[Snum]=Snum;
    
        while(!que1.empty()&&!que2.empty())
        {
            tsta1=que1.top();
            tsta2=que2.top();
            que1.pop();
            que2.pop();
    
            tnum1=tsta1.num;
            tnum2=tsta2.num;
            G1=tsta1.G;
            G2=tsta2.G;
    
            zhankai(t1,tnum1);
            zhankai(t2,tnum2);
    
            for(int i=0;i<3;++i)
                for(int j=0;j<3;++j)
                {
                    if(t1[i][j]==0)
                        x01=i,y01=j;
                    if(t2[i][j]==0)
                        x02=i,y02=j;
                }
    
            for(int i=0;i<4;++i)
            {
                if(judge(x01+step[i][0],y01+step[i][1])==0)
                    continue;
                
                swap(t1[x01][y01],t1[x01+step[i][0]][y01+step[i][1]]);
                temp=hebing(t1);
    
                if(rem[temp]==0)
                {
                    rem[temp]=i+1;
                    fa[temp]=tnum1;
                    H=getH(t1);
                    que1.push(state(H+G1+1,G1+1,temp));
                }
                else if(rem[temp]<0)
                {
                    fa[temp]=tnum1;
                    Mrem=rem[temp];
                    rem[temp]=i+1;
                    Mnum=temp;
    
                    return 1;
                }
    
                swap(t1[x01][y01],t1[x01+step[i][0]][y01+step[i][1]]);
            }
    
            for(int i=0;i<4;++i)
            {
                if(judge(x02+step[i][0],y02+step[i][1])==0)
                    continue;
    
                swap(t2[x02][y02],t2[x02+step[i][0]][y02+step[i][1]]);
                temp=hebing(t2);
    
                if(rem[temp]==0)
                {
                    rem[temp]=-(i+1);
                    son[temp]=tnum2;
                    H=getH(t2);
                    que2.push(state(H+G2+1,G2+1,temp));
                }
                else if(rem[temp]>0)
                {
                    son[temp]=tnum2;
                    Mrem=-(i+1);
                    Mnum=temp;
    
                    return 1;
                }
    
                swap(t2[x02][y02],t2[x02+step[i][0]][y02+step[i][1]]);
            }
        }
    
        return 0;
    }
    
    bool JiOujian(int (*m)[3])
    {
        int ni=0;
    
        for(int i=0;i<9;++i)
            for(int j=0;j<i;++j)
                if(m[i/3][i%3]&&m[j/3][j%3])
                    if(m[i/3][i%3]<m[j/3][j%3])
                        ++ni;
    
        return ni%2;
    }
    
    void solve(int (*m)[3])
    {
        if(JiOujian(m))
        {
            cout<<"unsolvable
    ";
            return;
        }
    
        memset(rem,0,sizeof(rem));
    
        Snum=hebing(m);
    
        if(Snum==Enum)
        {
            cout<<endl;
            return;
        }
    
        if(bfs())
            showans();
        else
            cout<<"unsolvable
    ";
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
    
        int m[3][3];
        char c;
    
        while(cin>>c)
        {
            m[0][0]=c=='x'?0:c-'0';
            cin>>c;
            m[0][1]=c=='x'?0:c-'0';
            cin>>c;
            m[0][2]=c=='x'?0:c-'0';
    
            for(int i=1;i<3;++i)
                for(int j=0;j<3;++j)
                {
                    cin>>c;
                    m[i][j]=c=='x'?0:c-'0';
                }
    
            solve(m);
        }
    
        return 0;
    }
    View Code

    IDA*+剪枝。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    
    using namespace std;
    
    const int maxn=400005;
    const int Enum=46233;
    const int jie[9]={1,1,2,6,24,120,720,5040,40320};
    const int Step[4][2]={{1,0},{0,-1},{-1,0},{0,1}};
    
    int ans[maxn];
    int Deep;
    int Node[3][3];
    int x01,y01;
    
    void swap(int &a,int &b)
    {
        int temp=a;
        a=b;
        b=temp;
    }
    
    bool judge()
    {
        for(int i=0;i<3;++i)
            for(int j=0;j<3;++j)
                if(Node[i][j]&&Node[i][j]!=i*3+j+1)
                    return 0;
    
        return 1;
    }
    
    bool JiOujian()
    {
        int ni=0;
    
        for(int i=0;i<9;++i)
            for(int j=0;j<i;++j)
                if(Node[i/3][i%3]&&Node[j/3][j%3])
                    if(Node[i/3][i%3]<Node[j/3][j%3])
                        ++ni;
    
        return ni%2;
    }
    
    int getH()
    {
        int reH=0;
    
        for(int i=0;i<3;++i)
            for(int j=0;j<3;++j)
                if(Node[i][j])
                    reH+=abs(i-(Node[i][j]-1)/3)+abs(j-(Node[i][j]-1)%3);
                else
                    reH+=abs(2-i)+abs(2-j);
    
        return reH;
    }
    
    void showans(int G)
    {
        for(int i=0;i<G;++i)
            if(ans[i]==0)
                cout<<'d';
            else if(ans[i]==1)
                cout<<'l';
            else if(ans[i]==2)
                cout<<'u';
            else
                cout<<'r';
    
        cout<<endl;
    }
    
    bool judgeBian(int x,int y)
    {
        if(x<0||y<0||x>2||y>2)
            return 0;
    
        return 1;
    }
    
    bool dfs(int G,int lasStep)
    {
        int H=getH();
    
        if(H+G>Deep)
            return 0;
    
        if(judge())
        {
            showans(G);
            return 1;
        }
    
        for(int i=0;i<4;++i)
        {
            if(i%2==lasStep%2&&i!=lasStep)
                continue;
    
            if(judgeBian(x01+Step[i][0],y01+Step[i][1])==0)
                continue;
    
            swap(Node[x01][y01],Node[x01+Step[i][0]][y01+Step[i][1]]);
            x01+=Step[i][0];
            y01+=Step[i][1];
    
            ans[G]=i;
    
            if(dfs(G+1,i))
                return 1;
    
            x01-=Step[i][0];
            y01-=Step[i][1];
            swap(Node[x01][y01],Node[x01+Step[i][0]][y01+Step[i][1]]);
        }
    
        return 0;
    }
    
    void solve()
    {
        if(JiOujian())
        {
            cout<<"unsolvable
    ";
            return;
        }
    
        Deep=1;
    
        while(1)
        {
            if(dfs(0,-1))
                return;
    
            ++Deep;
        }
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
    
        char c;
    
        while(cin>>c)
        {
            Node[0][0]=c=='x'?0:c-'0';
            cin>>c;
            Node[0][1]=c=='x'?0:c-'0';
            cin>>c;
            Node[0][2]=c=='x'?0:c-'0';
    
            for(int i=1;i<3;++i)
                for(int j=0;j<3;++j)
                {
                    cin>>c;
                    Node[i][j]=c=='x'?0:c-'0';
                }
    
            for(int i=0;i<3;++i)
                for(int j=0;j<3;++j)
                    if(Node[i][j]==0)
                        x01=i,y01=j;
    
            solve();
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    (转)一个JavaWeb项目开发总结
    (转)JAVA之桥接模式
    (转)Singleton 单例模式(懒汉方式和饿汉方式)
    (备忘)android模拟器摄像头模拟
    (原创)android中使用相机的两种方式
    (转)android中颜色矩阵colormatrix
    android中paint的setXfermode属性
    【贾志豪NOIP模拟题】慰问员工 cheer 【最小生成树】【对边权值的一些处理】
    【洛谷1340】兽径管理(最小生成树 Kruskal)(sort的一些技巧)【2012福建省信息学奥林匹克CCF NOIP夏令营第05天训练】
    【CSP2019】【洛谷5657】格雷码
  • 原文地址:https://www.cnblogs.com/whywhy/p/4230771.html
Copyright © 2011-2022 走看看