【 HDU1043-经典BFS+康拓展开 八数码】 (待更)
给定一个序列,由1~8数字和字母x组成,表示的是一个3*3的矩形。每次操作x都能与相邻的数字交换,问如何操作才能使得序列为{1,2,3,4,5,6,7,8,x}。
//多组数据-需要计算全部路径后直接输出
//反向搜索+打表(离线)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define MAX 400000
#define AIM 46234 //123456780对应的康托Hash值
bool v[MAX];
char path[MAX][40]; //总路径
int len; //路径长/*udlr*/
char *dir = "durl"; //反向搜索
int mov[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
//八数码状态结构体
struct Node{int s[9];int loc; //空位int status; //Hash值-排列值int fa; //记录父状态char d; //到此状态的移动方向
}n[MAX];
int fac[10] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 };
//康托逆展开-返回Hash值
int Inverse_cantor(int s[9])
{int sum = 0;for (int i = 0; i < 9; i++){int num = 0; //逆序数计数器for (int j = i + 1; j < 9; j++)if (s[j] < s[i])num++;sum += num*fac[9 - i - 1];}return sum + 1;
}
/*反向记录路径*/
void count_path(Node end)
{int status = end.status;int f = end.fa;len = 0;path[status][len++] = end.d;while (f){path[status][len++] = n[f].d;//方向记录f = n[f].fa; //查找父结点}
}
void BFS()
{memset(v, 0, sizeof(v));Node next; //下一临时状态int head = 0, tail = 0;/*目标状态*/for (int i = 0; i < 8; i++)n[0].s[i] = i + 1;n[0].s[8] = 0;n[0].loc = 8;n[0].status = AIM;v[AIM] = true;while (head <= tail) //模拟队列{//计算二维坐标int x = n[head].loc / 3;int y = n[head].loc % 3;for (int i = 0; i < 4; i++) //遍历四方向{int tx = x + mov[i][0];int ty = y + mov[i][1];if (tx < 0 || tx>2 || ty < 0 || ty>2)continue;//新状态更新next = n[head];next.loc = tx * 3 + ty; //计算新空位next.s[n[head].loc] = next.s[next.loc]; //原空位替换next.s[next.loc] = 0; //新空位next.fa = head;next.d = dir[i];next.status = Inverse_cantor(next.s);//判重并入队if (!v[next.status]){v[next.status] = true;count_path(next);n[++tail] = next;}}head++;}
}int main()
{/* BFS-打表 */BFS();/*input*/char ch[3];Node cur;while (scanf("%s", ch) != EOF){if (!strcmp(ch, "x"))cur.s[0] = 0, cur.loc = 0;else cur.s[0] = ch[0] - '0';for (int i = 1; i < 9; i++){scanf("%s", ch);if (!strcmp(ch, "x"))cur.s[i] = 0, cur.loc = i;else cur.s[i] = ch[0] - '0';}cur.status = Inverse_cantor(cur.s);/*output*/if (v[cur.status])printf("%s\n", path[cur.status]);elseprintf("unsolvable\n");}return 0;
}
还可以用A*好像
【 HDU1043-经典BFS+康拓展开 八数码】 (待更)相关推荐
- A_Star 康托展开 八数码问题
A_Star算法是一个主要用bfs实现的寻路算法,当数据量庞大的时候往往有更高的时间效率,可以看成是Dijkstra算法的升级版. "盲目搜索会浪费很多时间和空间, 所以我们在路径搜索时, ...
- 【蓝桥杯】九宫重排(BFS+康拓展开)
问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12 ...
- 九宫重拍(bfs + 康拓展开)
问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12 ...
- 康托展开(八数码问题)
定义: 把一个整数X展开成如下形式: X=a[n] ∗ *(n-1)!+a[n-1]∗*(n-2)!+-+a[i]*(i-1)!+-+a[2]*1!+a[1]*0![1] 其中a[i]为当前未出现的元 ...
- 【八数码问题】基于状态空间法的知识表示与状态搜索:无信息搜索(BFS/DFS) 启发式搜索(A*)
前言 一.问题引入 二.状态空间法 1. 知识及其表示 2. 状态空间法定义 3. 问题求解 三.基于状态空间搜索法解决八数码问题 1. 八数码问题的知识表示 2. 状态空间图搜索 1. 无信息搜索 ...
- 《人工智能》实验二——搜索技术(八数码问题)
必须记住下一步还可以走哪些点--OPEN表(记录还没有扩展的点) 必须记住哪些点走过了--CLOSED表(记录已经扩展的点 广度优先搜索 在应用BFS算法进行八数码问题搜索时需要open和closed ...
- hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数
题意: 题意就是八数码,给了一个3 * 3 的矩阵,上面有八个数字,有一个位置是空的,每次空的位置可以和他相邻的数字换位置,给你一些起始状态 ,给了一个最终状态,让你输出怎么变换才能达到目的. 思路: ...
- C++解题报告:详解经典搜索难题——八数码问题( 双向BFS A* 求解)
引言 AC这道八数码问题,你和楼教主就是兄弟了... 题目描述 在一个3*3的九宫格棋盘里,放有8个数码,数码的数字分别是1~8.棋盘中还有一个位置是空着的,用0表示.可以通过在九宫格里平移数码来改变 ...
- 八数码(康拓展开标记)及类似题
文章:https://www.cnblogs.com/Mychael/p/8282895.html 康拓展开,知道数列求排名 //3 2 5 4 1 59 #include<bits/stdc+ ...
最新文章
- python 自动化办公 案例_python自动化工具之pywinauto实例详解
- 干货丨11位机器学习大牛最爱算法全解
- 人类又双叒叕输了,就没人能管管这条“狗”吗?
- python支持中文吗_Python中使用中文
- python获取小时分钟
- MySQL高性能优化规范建议
- 机器学习系列|从白富美相亲看特征预处理与选择
- 通用mapper和分类实现
- cake php_如何(以及为什么)在Swinject中使用Cake Pattern
- 浅谈分布式存储中的网络通信
- 谈一谈Java 中 1000==1000 为false,而100==100 为true?
- 面试官:说一下JVM常用垃圾回收器的特点、优劣势、使用场景和参数设置
- Python MySQLdb 学习总结
- 随笔(1)——慢性意识障碍患者的智慧诊疗和远程管理
- c#语言asp.net实现treeview控件读数据库动态生成树的代码
- 使用maven给jar包生成对应的pom文件
- textarea 滚动条设置
- Kernel Method: 6.再生核希尔伯特空间理论
- 服务器内存只支持双路主板,壕到没朋友,支持双路18核CPU、16条内存、3路显卡的主板来了...
- 怎么把两个PDF合并成一个?建议收藏这些合并的方法