Aizu 0121 Seven Puzzle

7パズルは8つの正方形のカードとこれらのカードがぴたりと収まる枠を使って行います。それぞれのカードは互いに区別できるように、0,1,2....7と番号がつけられています。枠には、縦に2個、横に4個のカードを並べることができます。

7パズルを始めるときには、まず枠にすべてのカードを入れます。枠のなかで0のカードだけは、上下左右に隣接するカードと位置を交換することができます。たとえば、枠の状態が図( a )のときに、0のカードの右に隣接した、7のカードと位置を交換すれば、図( b )の状態になります。あるいは、図( a )の状態から0のカードの下に隣接した2のカードと位置を交換すれば図( c )の状態になります。カードの位置を入れ替える操作はこれだけが許されます。図( a )の状態で0のカードと上下左右に隣接するカードは7と2のカードだけなので、これ以外の位置の入れ替えは許されません。

ゲームの目的は、カードをきれいに整列して図( d )の状態にすることです。最初の状態を入力とし、カードをきれいに整列するまでに、必要な最小手数を出力して終了するプログラムを作成してください。ただし、入力されたカードの状態からは図( d )の状態に移ることは可能であるとします。

入力データは、1行に8つの数字が与えられます。これらは、最初の状態のカードの並びを表します。図( a )の数字表現は0,7,3,4,2,5,1,6に、図( c )は2,7,3,4,0,5,1,6となります。

図( a ) 0,7,3,4,2,5,1,6の場合 図( b ) 7,0,3,4,2,5,1,6の場合


図( c ) 2,7,3,4,0,5,1,6の場合 図( d ) 0,1,2,3,4,5,6,7(最終状態)

Input

1つ目のパズルの状態(整数;空白区切り)
2つ目のパズルの状態(整数;空白区切り)
     :
     :

与えられるパズルの数は1000以下です。

Output

1つ目のパズルの状態から最終状態へ移行する最小手数(整数)
2つ目のパズルの状態から最終状態へ移行する最小手数(整数)
            :
            :

Sample Input

0 1 2 3 4 5 6 7
1 0 2 3 4 5 6 7
7 6 5 4 3 2 1 0

Output for the Sample Input

0
1

28

这道题主要的解题思路是预处理,在程序执行前先把所有的可能性存储。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<map>
#include<iostream>
#include<queue>
using namespace std;
map<string,int>gmap;
int a[2][4];
int b[2][4];
int vis[4][2]={1,0,0,1,0,-1,-1,0};
struct text
{
    int a[2][4];
}st,tt,start;
queue<text> q;
char s[9];
char ss[9];
int temp=0;
int cnt=1;
bool check(int x,int y)
{
    if(x<0||y<0||x>=2||y>=4)
        return false;
    return true;
}
void bfs()
{
    while(!q.empty())
    {
        st=q.front();
        q.pop();
        int x,y;
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<4;j++)
            {
                if(st.a[i][j]==0)
                {
                   x=i;
                   y=j;
                }
                a[i][j]=st.a[i][j];
                ss[i*4+j]=st.a[i][j]+'0';
            }

        }
<span style="white-space:pre">	</span>//将结果存在map里
        for(int i=0;i<4;i++)
        {
            for(int j=0;j<2;j++)
            {
                int k=x+vis[i][0];
                int l=y+vis[i][1];
                if(check(k,l))
                {
                    int xx=a[x][y];
                    a[x][y]=a[k][l];
                    a[k][l]=xx;
                    for(int i=0;i<2;i++)
                    {
                        for(int j=0;j<4;j++)
                        {
                            s[i*4+j]=a[i][j]+'0';
                            tt.a[i][j]=a[i][j];
                        }
                    }
                    s[8]='\0';
                    if(!gmap[s]>0)
                    {
                        gmap[s]=gmap[ss]+1;
                        q.push(tt);
                    }
                    xx=a[x][y];
                    a[x][y]=a[k][l];
                    a[k][l]=xx;
                }
            }
        }
    }
}
int main()
{
    for(int i=0;i<8;i++)
        a[i/4][i%4]=i;
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<4;j++)
            start.a[i][j]=a[i][j];
    }
    for(int i=0;i<2;i++)
        {
            for(int j=0;j<4;j++)
            {
                s[i*4+j]=start.a[i][j]+'0';
            }
        }
    s[8]='\0';
    gmap[s]=1;
    q.push(start);
    bfs();//在程序执行前处理
    while(~scanf("%d",&a[0][0]))
    {
        for(int i=1;i<4;i++)
            scanf("%d",&a[0][i]);
        for(int i=0;i<4;i++)
            scanf("%d",&a[1][i]);
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<4;j++)
            {
                s[i*4+j]=a[i][j]+'0';
            }
        }
        s[8]='\0';
       // puts(s);
        printf("%d\n",gmap[s]-1);//直接输出map里的值
    }
}

你可能感兴趣的:(kk)