八数码 问题 BFS+Cantor
#include<bits/stdc++.h>
using namespace std;
const int LEN=362880; //状态总共362880
struct node{int state[9]; //记录一个八数码的排列,即一个状态int dis; //记录到起点的距离
};
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}}; //左、上、右、下顺时针方向,左上角坐标是(0,0)
int visited[LEN]={0}; //与每个状态对应记录,Cantor()函数对它置数,并判重
int start[9]; //开始状态
int goal[9]; //目标状态
long int factory[]={1,1,2,6,24,120,720,5040,40320,362880}; //Cantor()函数常用到的常数
bool Cantor(int str[],int n){long result=0;for(int i=0;i<n;i++){ //用康托展开判重int counted=0;for(int j=i+1;j<n;j++){if(str[i]>str[j]) //当前未出现的元素排在第几个++counted;}result+=counted*factory[n-i-1];}if(!visited[result]){ //没有被访问过visited[result]=1;return 1;}elsereturn 0;
}
bool bfs(){node head;memcpy(head.state,start,sizeof(head.state)); //复制起点的状态head.dis=0;queue<node> q; //队列中的内容是记录状态Cantor(head.state,9); //用康托展开判重,目的是对起点的visited[]赋初值q.push(head); //第一个进队列的是起点状态while(!q.empty()){ //处理队列head=q.front();q.pop(); //可在此处打印head.state,看弹出队列的情况int z;for(z=0;z<9;z++) //找这个状态中元素0的位置if(head.state[z]==0) break; //找到了 转化为二维,左上角是原点(0,0)int x=z%3; //横坐标int y=z/3; //纵坐标for(int i=0;i<4;i++){ //上下左右最多有可能有4个新状态int newx=x+dir[i][0]; //元素0转移后的新坐标int newy=y+dir[i][1];int nz=newx+3*newy; //转化为一维if(newx>=0 &&newx<3 &&newy>=0&&newy<3){ //未越界node newnode;memcpy(&newnode,&head,sizeof(struct node)); //复制这新的状态swap(newnode.state[z],newnode.state[nz]); //把0移动到新的位置newnode.dis++;if(memcmp(newnode.state,goal,sizeof(goal))==0) //与目标状态对比return newnode.dis; //到达目标状态,返回距离,结束if(Cantor(newnode.state,9)) //用康托展开判重q.push(newnode); //把新状态放在进队列中}}}return -1; //没找到
}
int main()
{for(int i=0;i<9;i++) cin>>start[i]; //初始状态for(int i=0;i<9;i++) cin>>goal[i]; //目标状态int num=bfs();if(num!=-1) cout<<num<<endl;else cout<<"Impossible"<<endl;return 0;
}
八数码 问题 BFS+Cantor相关推荐
- python 八数码_python 处理八数码 双向BFS 拼图游戏 | 学步园
我的代码一开始是单向的BFS 然后很慢,5分钟? 参照别人的代码后,改用双向BFS 很快 拼图问题 == 八数码问题 从开始状态start,进行BFS 同时,从结束状态end,进行BFS 如果左图能够 ...
- C++解题报告:详解经典搜索难题——八数码问题( 双向BFS A* 求解)
引言 AC这道八数码问题,你和楼教主就是兄弟了... 题目描述 在一个3*3的九宫格棋盘里,放有8个数码,数码的数字分别是1~8.棋盘中还有一个位置是空着的,用0表示.可以通过在九宫格里平移数码来改变 ...
- 习题:八数码难题(双向BFS)
八数码难题(wikioi1225) [题目描述] 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出 ...
- hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数
题意: 题意就是八数码,给了一个3 * 3 的矩阵,上面有八个数字,有一个位置是空的,每次空的位置可以和他相邻的数字换位置,给你一些起始状态 ,给了一个最终状态,让你输出怎么变换才能达到目的. 思路: ...
- 【 HDU1043-经典BFS+康拓展开 八数码】 (待更)
给定一个序列,由1~8数字和字母x组成,表示的是一个3*3的矩形.每次操作x都能与相邻的数字交换,问如何操作才能使得序列为{1,2,3,4,5,6,7,8,x}. //多组数据-需要计算全部路径后直接 ...
- AcWing 845. 八数码(3阶数字华容道):bfs求最短路,状态表示困难
文章目录 题目 题目分析 题目 题目链接:AcWing 845. 八数码(数字华容道) 在一个3×3的网格中,1~8这8个数字和一个"x"恰好不重不漏地分布在这3×3的网格中. 例 ...
- 八数码问题II-双向bfs和map标记
问题描述: 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是: 给出一种初始布局(初始状态)和目标布局( ...
- Poj 1077 eight(BFS+全序列Hash解八数码问题)
一.题意 经典的八数码问题,有人说不做此题人生不完整,哈哈.给出一个含数字1~8和字母x的3 * 3矩阵,如: 1 2 X 3 4 6 7 5 8 ...
- 移动拼图游戏(八数码问题) BFS版
小时候玩过的移动拼图游戏.有一个3*3的棋盘,其中有0-8这9个数字,0表示空格,每次移动只能把空格旁边的数字移到空格,即与0相邻的数字可以和0交换位置. 求从初始状态 2 3 0 7 1 6 5 8 ...
最新文章
- 二十三、死锁的处理策略---避免死锁(银行家算法)
- MyReport报表引擎2.2.0.0新功能
- 发现一个CentOS第三方源epel的仓库地址(repos.fedorapeople.org)
- 【算法分析与设计】二分查找平均查找长度的求解
- npm install readline-sync:同步获取用户通过键盘输入的值(+算法实例)
- Elasticsearch OOM(内存溢出)
- sql 左侧要固定最近一周的周四 怎么写_程序员啊,你怎么这么忙啊?
- matlab利用geotiffread读取tif文件报错:‘错误使用 tifflib, 无法打开 TIFF 文件’
- x64伪装进程路径 过PCHunter xxx ARK
- Windows 10 21H2 版本微软拼音全拼和双拼的快速切换
- 选择云盾抗ddos防火墙,信息安全有保障
- 原生JS实现中文简繁切换
- 解决百度首页导航栏透明度问题
- Python多维数组,已知多科成绩求英语成绩最高的学生名
- 如何使用left join,以及left join的分析
- 有限自动机和右线性文法笔记
- mongoDB使用及简单命令(忘记了密码怎么办、mongoDB密码重置、创建数据库、mongoDB启动停止)
- 09盘点:梦幻诛仙蜀门剑网三的营销启示
- Makecode编程软件打不开
- 数据库系统原理与实践题库及答案(完整版)