您的位置:首页 > 其它

蓝桥杯 九宫重排

2016-05-26 22:37 281 查看
  历届试题 九宫重排  

时间限制:1.0s   内存限制:256.0MB
      

问题描述

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





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

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

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

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

输入格式

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

输出格式

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

样例输入

12345678.

123.46758

样例输出

3

样例输入

13524678.

46758123.

样例输出

22

 

思路:广搜

#include"iostream"
#include"cstring"
using namespace std;
int f[10],dis[360000],d[4][2]={1,0,-1,0,0,1,0,-1};
bool vis[368805];
typedef int State[9];
State  st[364000],goal;
void ini()
{
f[0]=1;
for(int i=1;i<9;i++)
f[i]=f[i-1]*i;
}
bool visited(int x)
{
int code=0;
for(int i=0;i<9;i++)
{
int cnt=0;
for(int j=i+1;j<9;j++)
if(st[x][i]>st[x][j]) cnt++;
code+=cnt*f[8-i];
}
if(vis[code]) return false;
vis[code]=true;
return true;
}
int bfs()
{
ini();
int head=1,end=2;
dis[head]=0;
while(head<end)
{
State &a=st[head];
if(!memcmp(goal,a,sizeof(a)))  return head;
int z;
for(z=0;z<9;z++) if(!a[z]) break;
int x=z/3,y=z%3;
for(int i=0;i<4;i++)
{
int newx=x+d[i][0],newy=y+d[i][1];
int newz=newx*3+newy;
if(newx>=0&&newx<3&&newy<3&&newy>=0)
{
State &t=st[end];
memcpy(&t,&a,sizeof(a));
swap(t[newz],t[z]);
dis[end]=dis[head]+1;
if(visited(end)) end++;
}
}
head++;
}
return 0;
}
int main()
{
char a[10];
cin>>a;
for(int i=0;i<strlen(a);i++)
if(a[i]=='.') goal[i]=0;
else  goal[i]=a[i]-'0';
cin>>a;
for(int i=0;i<strlen(a);i++)
if(a[i]=='.') st[1][i]=0;
else  st[1][i]=a[i]-'0';
int rst=bfs();
if(rst==0) cout<<"-1"<<endl;
else cout<<dis[rst]<<endl;
return 0;
}


详细记录

评测点序号评测结果得分CPU使用内存使用下载评测数据
1正确20.000ms16.75MB输入 输出
2正确20.000ms16.74MBVIP特权
3正确20.0015ms16.74MBVIP特权
4正确20.0046ms16.74MBVIP特权
5正确20.0062ms16.74MBVIP特权
推荐一个著名的OJ网站

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