九宫重排  
时间限制:1.0s   内存限制:256.0MB
 
问题描述
  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
  输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
  输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22
 
#include <queue> 
#include <cstring>
#include <iostream>
using namespace std;

struct sb{
    int loc, c[10], step;
} Node;
int dir[4][2]={0, 1, 0, -1, -1, 0, 1, 0};
int jc[9]={1, 1, 2, 6, 24, 120, 720, 5054, 40320};

int kangtuo(int c[])
{
    int sum =0, k;
    for(int i=0; i< 9; i++)
    {
        k =0;
        for(int j=i+1; j< 9; j++)
            if(c[j] <c[i]) k++;
        sum+= k* jc[8-i];
    } 
    return sum;
}
int find(int c[],  int num1, int num2)
{
    if(num1== num2) return 0;
    queue<sb> q;
    sb now, next;
    int f[400000];
    
    memset(f, 0, sizeof(f));
    
    for(int i=0; i< 9; i++)
    {
        if(c[i]== 9) now.loc = i;
        now.c[i]= c[i];
    }
    now.step =0;
    
    q.push(now);
    while(!q.empty())
    {
        now= q.front(); q.pop();
        for(int e=0; e<4; e++)
        {
            int x= now.loc/3+dir[e][0];
            int y= now.loc%3+dir[e][1];
            if(x>= 0&& x< 3 && y>=0 && y< 3){
                next= now;
                next.step++;
                next.loc = x*3+y;
                int tm= next.c[now.loc];
                next.c[now.loc]=next.c[x*3+y];
                next.c[x*3+y]= tm; 
                num1 =kangtuo(next.c);
                if(num1== num2) return next.step;
                if(!f[num1]){
                    f[num1]=1;
                    q.push(next);
                }
            }
        }
    }
    return -1;
}
int main()
{
    int c[10], tc[10], num1, num2, step;
    char ch[10], tch[10];
    scanf("%s%s", ch, tch) ;
    for(int i=0; i< 9; i++)
    {
        if(ch[i]>= '1' && ch[i] <= '8') c[i]= ch[i]-'0';
        else c[i]=9;
        
        if(tch[i]>= '1' && tch[i] <= '8') tc[i]= tch[i]- '0';
        else tc[i]= 9;    
    }
    
    num1= kangtuo(c);
    num2= kangtuo(tc);
    
    printf("%d\n", find(c, num1, num2));
    return 0;
}

 

posted on 2016-05-25 18:47  cleverbiger  阅读(334)  评论(0编辑  收藏  举报