hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

2024-09-09 17:48

本文主要是介绍hdu1043(八数码问题,广搜 + hash(实现状态压缩) ),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。

#include<iostream>
#include<algorithm>
#include<string>
#include<stack>
#include<queue>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#include<math.h>#define eps 1e-9
#define N 400000
#define P system("pause")
using namespace std;
struct node
{int map[9];int zero;int hash_id;     
};
int fac[]={1,1,2,6,24,120,720,5040,40320};
int d[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; //因为是逆序查找,所以上下左右,变成了 
char dir[]={'d','u','r','l'};                                              //下上右左   
int hash[N];
string path[N];
int cantor(int *s)     //康拓扩展求hash值 
{int count,i,j;int sum=0;for(i=0;i<8;i++){count=0;for(j=i+1;j<9;j++)if(s[i]>s[j])  count++;sum+=(fac[8-i]*count);          }return sum;
}void bfs()
{                   //从目标开始逆向搜索,枚举每种可能出现的排列int i;node u,v;u.zero=8;u.map[8]=0;for(i=0;i<8;i++)u.map[i]=i+1;u.hash_id=cantor(u.map);           hash[u.hash_id]=1;path[u.hash_id]="";queue<node> q;q.push(u);while(!q.empty()){u=q.front();q.pop();int x=u.zero/3;        //找到0的位置 int y=u.zero%3;for(i=0;i<4;i++){int nx=x+d[i][0];int ny=y+d[i][1];if(nx>=0 && nx<3 && ny>=0 && ny<3){int k=nx*3+ny; //一维数组下标                     v=u;v.zero=k;v.map[u.zero]=u.map[k];v.map[k]=0;v.hash_id=cantor(v.map);}if(!hash[v.hash_id]){hash[v.hash_id]=1;path[v.hash_id]=path[u.hash_id];path[v.hash_id]+=dir[i];                                  q.push(v);                      }}                 }}int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);ccmemset(hash,0,sizeof(hash));bfs();char c;int s[9];while(cin>>c){if(c=='x') s[0]=0;else s[0]=c-'0';for(int i=1;i<9;i++)        {cin>>c;if(c=='x') s[i]=0;else s[i]=c-'0';        }int k=cantor(s);if(!hash[k])  printf("unsolvable\n");else{string ss=path[k];reverse(ss.begin(),ss.end()); cout<<ss<<endl;    }}   //P;                               return 0;    
}


这篇关于hdu1043(八数码问题,广搜 + hash(实现状态压缩) )的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1151856

相关文章

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法