您的位置:首页 > 其它

历届试题 九宫重排

2015-04-13 19:09 162 查看
问题描述

  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。





  我们把第一个图的局面记为:12345678.

  把第二个图的局面记为:123.46758

  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。

  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。

输入格式

  输入第一行包含九宫的初态,第二行包含九宫的终态。

输出格式

  输出最少的步数,如果不存在方案,则输出-1。

样例输入

12345678.

123.46758

样例输出

3

样例输入

13524678.

46758123.

样例输出

22

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
char mp[10];
char e[10];
int dp[9*8*7*6*5*4*3*2*10];
//康拓
int ct[] = {1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int getVal(char s[])
{
int rt = 0, i;
for(i=0; i<9; i++)
{
rt += (s[i] - '0')*ct[i];
}
return rt;
}
//
//
int fx[] = {1,0,-1,0,1};
struct node{
char g[10];
int x, y;
int pay;
};
void charsCopy(char a[], char b[])
{
for(int i=0; i<9; i++)
b[i] = a[i];
}
int work(int s)
{
memset(dp, -1, sizeof (dp));
node a, b;
int i, k, ek = getVal(e);
charsCopy(mp, a.g);
a.x = s/3;
a.y = s%3;
a.pay = 0;
k = getVal(a.g);
if(k == ek)return 0;
dp[k] = 0;
queue<node>q;
q.push(a);
while(!q.empty())
{
a = q.front();
q.pop();
for(i=0; i<4; i++)
{
b.x = a.x + fx[i];
b.y = a.y + fx[i+1];
if(b.x<0 || b.x>2 || b.y<0 || b.y>2)continue;
charsCopy(a.g, b.g);
b.g[a.x*3 + a.y] = b.g[b.x*3 + b.y];
b.g[b.x*3 + b.y] = '0';
b.pay = a.pay + 1;

k = getVal(b.g);
if(dp[k]==-1)
{
dp[k] = b.pay;
if(k==ek)
{
return b.pay;
}
q.push(b);
}
}
}
}
int main()
{
int i, s;
cin>>mp;
cin>>e;
for(i=0; i<9; i++)
{
if(mp[i]=='.')
{
mp[i] = '0';
s = i;
}
if(e[i]=='.')e[i] = '0';
}
cout << work(s) << endl;;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: