问题描述
  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
  
  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
  输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
  输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22

解题思路:采用类似于迷宫老鼠求最短路问题,利用BFS找所有的情况,关键问题在于判重,我们知道一共有9!种可能,利用康拓展开,就可以确定每种排列位于所有排列中的位置。

康拓展开
定义:X=an*(n-1)!+an-1*(n-2)!+…+ai*(i-1)!+…+a21!+a10!
2的后面有1个数比2小,即 1 * 2!
1的后面没有比1小的数,即 0 * 1!
3的后面没有比3小的数,即 0 * 0!
X = 12!+01!+0*0! = 2

这样我们声明一个数组st[9!]来记录哪个状态被访问过了;同时我们声明一个二维数组rec[9!][9]来表示某个状态的排列是什么。

代码如下

#include <iostream>
#include <queue>
using namespace std;int jing[4][4] = {0};int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};struct poi{ //记录0在二维表中的位置,以及当前排列的状态(即所有排列中的位置),以及到这个位置的步数int x; //横坐标int y;//纵坐标int state;//排列状态int step = 0;//到该的步数poi(int xx,int yy,int st,int ste){x = xx;y = yy;state = st;step = ste;}
};queue<poi>que; //维护一个队列int rec[362880][9];//记录所有状态对应的排列
int st[362880] = {0}; //记录那个状态被访问过了int kangtuo(int x[])  //康拓展开求位置
{int fac[]={1,1,2,6,24,120,720,5040,40320};int i,j,t,sum;sum = 0;for(i=0;i<9;i++){t = 0;for(j=i+1;j<9;j++){if(x[j]<x[i])t++;}sum = sum+t*fac[8-i];}return sum;
}poi des(1,1,1,0); //目标排列,参数随便写的,后面会赋值int bfs(int tx,int ty,int sta){ //起始位置tx,ty以及起始状态que.push(poi(tx,ty,sta,0)); //压入第一个位置while(!que.empty()){//    cout<<que.size()<<endl;poi tp = que.front(); //取出一个位置int x = tp.x;int y = tp.y;que.pop();int*tarr = rec[tp.state];for(int i = 1;i <= 3;i++){ // 把当前排列状态所对应的一维排列转换成二维的for(int j = 1;j <= 3;j++){jing[i][j] = tarr[3*(i - 1) + j  - 1]; }}if(tp.state == des.state){ //当前状态即为目标状态,找到了return tp.step;}for(int i = 0;i < 4;i++){ //像四个方向移动x = x + dir[i][0];y = y + dir[i][1];if(x >= 1 && x <= 3 && y >= 1 && y <= 3){ //越界判断//移动#############int t  = jing[x][y];jing[x][y] = jing[x - dir[i][0]][y - dir[i][1]];jing[x - dir[i][0]][y - dir[i][1]] = t;///移动########################int tarr[9];for(int i = 1; i <= 3;i++){for(int j = 1;j <= 3;j++){tarr[3*(i - 1) + j - 1] = jing[i][j];}}int stt = kangtuo(tarr);//装换成状态 if(!st[stt]){ //此状态没有被访问过que.push(poi(x,y,stt,tp.step + 1));//压入新的状态,步数为上一状态步数+1st[stt] = 1;for(int i = 0;i < 9;i++){rec[stt][i] = tarr[i];}}//恢复移动################t  = jing[x][y];jing[x][y] = jing[x - dir[i][0]][y - dir[i][1]];jing[x - dir[i][0]][y - dir[i][1]] = t;//恢复移动###############}x = x - dir[i][0];y = y - dir[i][1];} }return -1;
}int main(){string s1;string s2;cin>>s1;cin>>s2;int sa[9] = {0};int sb[9] = {0};int start = 0;for(int i = 0;i < 9;i++){if(s1[i] == '.'){ //‘.’不处理,视为0start = i; }else{sa[i] = s1[i] - '0';}if(s2[i] != '.'){sb[i] = s2[i] - '0';}}int st1 = kangtuo(sa); //起始排列状态int st2 = kangtuo(sb); //目标排列状态des.state = st2;for(int i = 0;i < 9;i++){ //把起始排列按状态存入rec中rec[st1][i] = sa[i];}st[st1] = 1; //认为起始状态被访问过了cout<<bfs(start / 3 + 1,start % 3 + 1,st1);return 0;
}

【蓝桥杯】九宫重排(BFS+康拓展开)相关推荐

  1. 九宫重排_康拓展开_bfs

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

  2. 蓝桥杯——九宫重排、青蛙跳杯子

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

  3. 蓝桥杯 九宫重排 java_九宫重排--蓝桥杯国赛历年真题

    标题:九宫重排 如图1的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片能够移动到空格中.通过若干次移动,能够造成图2所示的局面. 咱们把图1的局面记为:1234567 ...

  4. 蓝桥杯九宫重排(bfs+用set去重)

    题目连接 #define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<iostream> #include<que ...

  5. 蓝桥杯 九宫重排 java_【蓝桥杯】历届试题 九宫重排

    #include#include#include#include using namespacestd;int dir[4] = {-3, 3, -1, 1}; //x, y 上 -3 下 +3 左 ...

  6. 蓝桥杯-九宫重排 (搜索)

    问题描述:在九宫格中放置8个数,有一个为空格.给定初始状态九宫格,和目标状态九宫格,问需要多少步可以将初始状态变成目标状态.如果无法达到输出-1,如果可以达到,输出最少的步骤数. 问题分析:本题属于搜 ...

  7. 九宫重拍(bfs + 康拓展开)

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

  8. 蓝桥杯.跳蚱蜢(BFS)

    Question: Result: 20 Solve: BFS板子题,跟POJ的八数码如出一辙,因为是填空题,超时也不怕,输出结果就行,也就没必要双向搜索,单向是绝对会超时的 注意点: 将状态存为st ...

  9. 备战蓝桥杯-双指针、BFS

    备战蓝桥杯所有笔记 双指针

最新文章

  1. 关于C语言中的数组指针、指针数组以及二级指针
  2. Java并发编程之CountDownLatch、CyclicBarrier和Semaphore
  3. 通用社区登陆组件技术分享(开源)中篇:OAuth 登陆组件流程及组件集成方法...
  4. pip包重新安装mysql_Ubuntu pip 安装 mysql-python包出错
  5. 香帅的北大金融学课笔记6 -- 货币基金
  6. 我是如何学习写一个操作系统(八):内存管理和段页机制
  7. java spi机制_Java是如何实现自己的SPI机制的? JDK源码(一)
  8. 最小编辑代价-golang
  9. Qt学习笔记-使用shape() 使得碰撞更加精确
  10. cocos2d-x中CCEditbox导出到lua
  11. Puppeteer -headless Chrome 的 Node.js API
  12. BatchPhoto Pro for Mac(照片批量处理软件)
  13. 计算机局域网中处理器可以共享么,局域网中怎么设置可共享主机的应用程序及CPU资源。...
  14. 光栅透过率计算 (Matlab)
  15. 2021-03-04
  16. face_alignment库获取人脸图片landmark示例
  17. 收藏 90+深度学习开源数据集整理|包括目标检测、工业缺陷、图像分割等多个方向
  18. ae合成设置快捷键_【实用向】AE必备小技巧
  19. html行内设置样式,Js获取/设置行内样式和非行内样式
  20. 计算机分区的优点,NTFS分区格式的优点及其转换

热门文章

  1. 苹果开发者账号 转让已上架的App应用(更换开发者账号)
  2. 提高睡眠质量的助眠好物,双十一值得买的助眠好物
  3. 利用二进制变量相或,得出唯一整形变量,以表示某事物的叠加态
  4. Android刷linux系统
  5. UGC社区的搭建方法,从初期到活跃。
  6. 赞美是感情生活的“保鲜剂”:关于赞美分享的fMRI研究
  7. Python中type的意思
  8. matomo安装及使用
  9. 食品科学与工程考研可以考计算机吗,食品科学与工程考研考哪些科目
  10. 智慧工厂实施建设方案-数字化