Description

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

我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。

Input

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

Output

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

Sample Input

样例输入1
12345678.
123.46758 样例输入2
13524678.
46758123.

Sample Output

样例输出1
3 样例输出2
22

Source

蓝桥杯
 
分析:暴力bfs会超时
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF 99999999
#define me(a,x) memset(a,x,sizeof(a))
int mon1[]= {,,,,,,,,,,,,};
int mon2[]= {,,,,,,,,,,,,};
int dir[][]= {{,},{,-},{,},{-,}};
int fac[] = {, , , , , , , , , };//i的阶乘 LL getval()
{
LL ret();
char c;
while((c=getchar())==' '||c=='\n'||c=='\r');
ret=c-'';
while((c=getchar())!=' '&&c!='\n'&&c!='\r')
ret=ret*+c-'';
return ret;
}
void out(int a)
{
if(a>)
out(a/);
putchar(a%+'');
}
int kt(int a[],int n)//康托展开
{
int ans=;
for(int i=;i<=n;i++)
{
int c=;
for(int j=i+;j<=n;j++)
{
if(a[j]<a[i])
c++;
}
ans+=(c*fac[n-i]);
}
return ans+;
} char str1[],str2[];
int a[][],b[][];
int sx,sy;
int t[];
int h;
int w;
bool vis[]; struct node
{
int x,y,step;//x,y代表空格位置
int c[][];//九宫格数组
node(int xx,int yy,int ss,int cc[][])//初始化
{
x=xx;
y=yy;
step=ss;
for(int i=; i<=; i++)
for(int j=; j<=; j++)
c[i][j]=cc[i][j];
}
int getkt()//得到结点数组的康托展开值
{
h=;
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
t[h++]=c[i][j];
}
}
return kt(t,);
}
}; void init()//初始化
{
int cnt=;
for(int i=; i<=; i++)//得到原始九宫格
{
for(int j=; j<=; j++)
{
if(str1[cnt]=='.')
a[i][j]=,sx=i,sy=j;
else
a[i][j]=str1[cnt]-'';
cnt++;
}
}
cnt=;
for(int i=; i<=; i++)//得到目标九宫格
{
for(int j=; j<=; j++)
{
if(str2[cnt]=='.')
b[i][j]=;
else
b[i][j]=str2[cnt]-'';
cnt++;
}
}
me(vis,false);//九宫格状态数组
h=;
for(int i=;i<=;i++)//得到目标九宫格的康托展开值
{
for(int j=;j<=;j++)
{
t[h++]=b[i][j];
}
}
w=kt(t,);
}
int check(int x,int y)//边界约束
{
if(x<=&&x>=&&y<=&&y>=)
return ;
return ;
}
int bfs(int x,int y,int a[][])
{
queue<node> q; q.push(node(x,y,,a));
vis[node(x,y,,a).getkt()]=; while(!q.empty())
{
int x=q.front().x;
int y=q.front().y;
int step=q.front().step;
int c[][];
for(int i=; i<=; i++)
for(int j=; j<=; j++)
c[i][j]=q.front().c[i][j];
q.pop(); for(int i=; i<; i++)
{
int xx=x+dir[i][];
int yy=y+dir[i][];
int ss=step+; int cc[][];
if(check(xx,yy)==)//越界
continue; for(int i=; i<=; i++)
for(int j=; j<=; j++)
cc[i][j]=c[i][j];
cc[x][y]=cc[xx][yy];//移动
cc[xx][yy]=; if(vis[node(xx,yy,ss,cc).getkt()]==)//判断该状态的九宫格有没有搜索过
{
if(node(xx,yy,ss,cc).getkt()==w)//搜索到了目标
{
return ss;//返回步数
}
int temp=node(xx,yy,ss,cc).getkt(); vis[temp]=;//标记该状态的九宫格已经搜索过
q.push(node(xx,yy,ss,cc));
} }
}
return -;
}
int main()
{
while(~scanf("%s",str1))
{
scanf("%s",str2);
init(); int ans=bfs(sx,sy,a);
printf("%d\n",ans);
}
}

蓝桥杯 历届试题 九宫重排 (bfs+康托展开去重优化)的更多相关文章

  1. Java实现 蓝桥杯 历届试题 九宫重排

    问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12 ...

  2. 算法笔记_183:历届试题 九宫重排(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成 ...

  3. 蓝桥杯OJ PREV-19 九宫重排

    题目描写叙述:   历届试题 九宫重排   时间限制:1.0s   内存限制:256.0MB        问题描写叙述 如以下第一个图的九宫格中,放着 1~8 的数字卡片.另一个格子空着.与空格子相 ...

  4. 蓝桥杯历届试题 地宫取宝 dp or 记忆化搜索

    问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...

  5. 2013年第四届蓝桥杯国赛 九宫重排(HashMap+双BFS优化)

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

  6. 蓝桥杯 历届试题 剪格子(dfs搜索)

    历届试题 剪格子 时间限制:1.0s   内存限制:256.0MB 问题描述 如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+ |* || +--****--+ ||* | ** ...

  7. 蓝桥杯 历届试题 网络寻路(dfs搜索合法路径计数)

    X 国的一个网络使用若干条线路连接若干个节点.节点间的通信是双向的.某重要数据包,为了安全起见,必须恰好被转发两次到达目的地.该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径 ...

  8. 蓝桥杯 历届试题 约数倍数选卡片 (经典数论+DFS)

    闲暇时,福尔摩斯和华生玩一个游戏: 在N张卡片上写有N个整数.两人轮流拿走一张卡片.要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数.例如,某次福尔摩斯拿走的卡片上写着数字“6”,则接下来华生可 ...

  9. 蓝桥杯  历届试题 幸运数  dfs

    历届试题 幸运数 时间限制:1.0s   内存限制:256.0MB 问题描述 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的"筛法"生成 . 首先从1开始写出自然数1,2, ...

随机推荐

  1. 【代码笔记】iOS-HTTPQueue下载图片

    一,工程图. 二,代码. ViewController.h #import <UIKit/UIKit.h> #import "ASIHTTPRequest.h" #im ...

  2. profile,bashrc,.bash_profile,.bash_login,.profile,.bashrc,.bash_logout浅析 Part 2

    profile,bashrc,.bash_profile,.bash_login,.profile,.bashrc,.bash_logout浅析 Part 2   by:授客 QQ:103355312 ...

  3. SurfaceViewVideoList网络获取视频播放

    主布局: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:andro ...

  4. ionic之angular1.X缓存问题解决

    众所周知ionic的angular1.X解决缓存的问题有: 1.在app.js里面修改:默认是true,设置了缓存 .state('tab.msg-main', { url: '/msg-main', ...

  5. MAC安装了mumu安卓模拟器,但无法检测到该模拟器

    1.adb   devices  看不到模拟器 2.adb connect 127.0.0.1:5555 3.adb kill-server 没有报错,即成功 4. adb start-server ...

  6. 韩顺平php从入门到精通

    37 整型细节说明 $a; echo $a; var_dump($a) //NULL 一个数总是要占用内存空间(字节),在php中一个整数一般占用四个字节(与平台相关),一个字节占用8bit php的 ...

  7. PHP用正则匹配字符串中的特殊字符防SQL注入

    本文出至:新太潮流网络博客 /** * [用正则匹配字符串中的特殊字符] * @E-mial wuliqiang_aa@163.com * @TIME 2017-04-07 * @WEB http:/ ...

  8. scaffold-dbcontext 命令使用说明

    工具的scaffold-dbcontext(数据库上下文脚手架)指令来生成models和context. 指令详细介绍: Scaffold-DbContext [-Connection] <St ...

  9. sha256sum和 md5sum 命令之间的区别

    Short answer: For verifying ISOs, there is no practical difference, use whichever you want, as long ...

  10. November 04th, 2017 Week 44th Saturday

    It does not do to dwell on dreams and forget to live. 整天沉溺于梦想而忘记如何好好生活,毫无意义. Bingo, and I think it i ...