笔记:记录状态并判重的方法

news2024/12/29 7:47:51

题目(八数码问题)

编号为1-8的8个正方形滑块被摆成3行3列(有一个格子留空),如下图所示

815
736
42

每次可以把与空格相邻的滑块(有公共边才算相邻)一道空格中,而它原来的位置就成为了新的空格。给定初始局面和目标局面(用0表示空格),你的任务是计算出最少的移动步数。如果无法到达目标局面,则输出-1

解法思路

简单来说就是无权图的最短路径问题(和我昨天看到的魔方问题差不多),可以用bfs来做

如果想看看有权图的最短路径问题,可以看看下面这题:

OpenJudge - 19G:海拔

我做这题的思路:

好了言归正传

这题难点在于对状态的记录的问题:如果声明一个9维数组vis,总共有9^9=387420489个项,太多了,内存直呼根本塞不下。如果把9个元素合并成一个数字,最大的数字是876543210,甚至更大

而实际的结点数量并没有这么多,0~8的全排列只有9!= 362990个,如果按照上面的方法,有大量的内存会被浪费

方法一

直接使用STL的集合set。把状态转化为9位十进制整数,就可以用set<int>判重了

set<int> vis;
void init_lookup_table{vis.clear();}
int try_to_insert(int s){
    int v = 0;
    //将s中的状态转化为数字并放入v中(伪代码)
    if(vis.count(v)) return 0;
    vis.insert(v);
    return 1;
}

很简单对吧,但是效率低,建议在时间紧迫或对效率要求不太高的情况下使用

方法二

把排列“变成”整数,然后只开一个一维数组。也就是说,设计一套排列的编码和解码函数,把0~8的全排列和0~362879的整数一一对应起来

int vis[362880], fact[9];
void init_lookup_table(){
    fact[0] = 1;
    for(int i = 1; i < 9; i++) fact[i] = fact[i - 1] * i;
}
int try_to_insert(int s){
    int code = 0; //把st[s]映射到整数code(st为二维数组,记录状态,第二维记录各个数字)
    for(int i = 0; i < 9; i++){
        int cnt = 0;
        for(int j = i + 1; j < 0; j++) if(st[s][j] < st[s][i]) cnt++;
        code += fact[8 - i] * cnt;
    }
    if(vis[code]) return 0;
    return vis[code] = 1;
}

屌吧,屌爆了

原理巧妙(我根本想不到),时间效率也非常高,但编码解码法的适用范围并不大:如果总结点数非常大,编码也会非常大,数组还是开不下

方法三

想必诸位都猜到了

使用哈希技术。简单地说,就是要把结点“变成”整数,但是不必一一对应。换句话说,只需设计一个所谓的哈希函数h(x),然后将任意结点x映射到某个给定范围[0, M - 1]的整数即可,其中M是程序员根据可用内存大小自选的。在理想情况下,只开一个大小为M的数组就能完成判重,但此时往往会有不同结点的哈希值相同,因此需要把哈希值相同的状态组织成链表

typedef int State[9];
const int hashsize = 1000003;
const int maxstate = 1000000;

State st[maxstate];//状态数组
int head[hashsize], next[maxstate];
void init_lookup_table(){memset(head, 0, sizeof(head);}
int hash(State &s){
    int v = 0;
    for(int i = 0; i < 9; i++) v = v * 10 + s[i];//把9个数字组成9位数
    return v % hashsize;//确保哈希值是不超过哈希表大小的非负整数
}
int try_to_insert(int s){
    int h = hash(st[s]);
    int u = head[h];
    while(u){
        if(memcmp(st[u], st[s], sizeof(st[s])) == 0) return 0;//找到了,不用插入
        u = next[u];//继续找
    }
    next[s] = head[h];
    head[h] = s;
    return 1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1857124.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3.3 的 defineOptions 的使用,方便在 setup 语法糖中为组件命名和控制父子属性透传,包含在线运行实例欧

defineOptions 是 Vue3.3 的新的宏&#xff0c;可以通过 defineOptions 宏在 <script setup> 中使用选项式 API&#xff0c;也就是说可以在一个宏函数中设置 name, props, emits, render, 控制是否允许父子非 props 的属性透传等功能。 defineOptions 可以直接在 setup …

新能源商业浪潮来袭:企业巨轮扬帆商海,共绘绿色未来蓝图

随着全球气候变化问题日益严峻&#xff0c;新能源产业正成为推动经济发展的新引擎。 在这场新能源商业浪潮中&#xff0c;众多企业如同巨轮一般&#xff0c;扬帆商海&#xff0c;共同绘制绿色未来的宏伟蓝图。 新能源产业的崛起&#xff0c;不仅为经济发展注入了新的活力&…

linux下进度条的实现

一、代码一版 使用模块化编程 1.processbar.h #include<stdio.h> #define capacity 101 //常量使用宏定义 #define style //符号方便后续修改 extern void processbar();修饰变量的时候一定要带extern&#xff0c;修饰函数的时候可以省略&#xff0c;因为没有函数体就…

将Windows11右键菜单修改为Windows10风格

Windows11更新后&#xff0c;右键菜单很多功能隐藏起来了&#xff0c;使用时需要点击“显示更多选型”才能获取完整功能。为了能获得Windows10右键菜单丝滑的体验&#xff0c;我总结了以下方法。 方法一&#xff1a;控制台操作法 按住winR打开运行窗口 输入cmd&#xff0c;…

护眼灯和普通台灯有什么区别?劣质护眼台灯宣传的三大套路

护眼灯和普通台灯有什么区别&#xff1f;围绕这一问题的讨论颇多。然而&#xff0c;真正体验过护眼台灯的人会深知&#xff0c;它与普通台灯之间的差异远非一般&#xff0c;涉及照明效果、色温调节、蓝光控制、闪烁问题及功能性设计等诸多层面。为了让更多人透彻理解这两者之间…

【代码阅读】SSC:Semantic Scan Context for Large-Scale Place Recognition

一、主函数 官方开源的代码提供了四个主函数&#xff0c;其中eval_pair.cpp和eval_top1.cpp是一组&#xff0c;分别用于计算两帧的相似度分数以及一帧点云在所有的51帧点云中相似度最高的25帧的相似度分数。eval_seq.cpp是在eval_top1.cpp的基础上&#xff0c;给了一堆序列&am…

视频格式转换方法:如何使用视频转换器软件转换视频

众所周知&#xff0c;目前存在许多不同的视频和音频格式。但我们的媒体播放器、移动设备、PC 程序等仅兼容少数特定格式。例如&#xff0c;如果不先将其转换为 MP4、MOV 或 M4V 文件&#xff0c;AVI、WMV 或 MKV 文件就无法在 iPhone 上播放。 视频转换器允许您将一种视频格式…

[经验] candy是什么意思英语翻译 #笔记#其他#职场发展

candy是什么意思英语翻译 1、candy的意思 Candy是英语中的一个词汇&#xff0c;意思是糖果、糖果制品。Candy意为果脯的意思也不是很常见。 糖果是一种富含糖分的食品&#xff0c;主要由砂糖、粘合剂和食用色素等组成。糖果的种类可以很多&#xff0c;有硬糖、软糖、巧克力、…

OpenAI CTO米拉·穆拉提谈未来:AI一年半后达到博士水平

人工智能&#xff08;AI&#xff09;领域近年来的发展迅猛&#xff0c;特别是在大语言模型&#xff08;LLM&#xff09;的进步上。最近&#xff0c;OpenAI的首席技术官&#xff08;CTO&#xff09;米拉穆拉提&#xff08;Mira Murati&#xff09;在达特茅斯学院的一次采访中&am…

捷瑞数字业绩波动性明显:关联交易不低,募资必要性遭质疑

《港湾商业观察》施子夫 5月22日&#xff0c;山东捷瑞数字科技股份有限公司&#xff08;以下简称&#xff0c;捷瑞数字&#xff09;及保荐机构国新证券披露第三轮问询的回复&#xff0c;继续推进北交所上市进程。 从2023年6月递表开始&#xff0c;监管层已下发三轮审核问询函…

QT实现人脸识别

QT实现人脸识别 Face.pro文件&#xff1a; QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # d…

我在高职教STM32——LCD液晶显示(4)

大家好&#xff0c;我是老耿&#xff0c;高职青椒一枚&#xff0c;一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次&#xff0c;同行应该都懂的&#xff0c;老师在课堂上教学几乎是没什么成就感的。正因如此&#xff0c;才有了借助 CSDN 平台寻求认同感和成就…

AIGC发展方向和前景

引言 背景介绍 AIGC的定义及其发展历程 AIGC&#xff0c;即人工智能生成内容&#xff0c;是近年来在人工智能领域兴起的一项重要技术。它通过使用机器学习和深度学习等技术&#xff0c;使得计算机能够自动生成各种形式的数字内容&#xff0c;如文本、图像、音频和视频等。 …

钢铁企业环保创A

朗观视觉小编观察发现&#xff0c;在当下全球环保浪潮的推动下&#xff0c;钢铁企业作为传统重工业的代表&#xff0c;正面临着前所未有的挑战与机遇。为了实现可持续发展&#xff0c;许多钢铁企业纷纷加入到环保创A的行列中&#xff0c;通过技术创新和管理升级&#xff0c;推动…

Lipowerline5.0 雷达电力应用软件下载使用

1.配网数据处理分析 针对配网线路点云数据&#xff0c;优化了分类算法&#xff0c;支持杆塔、导线、交跨线、建筑物、地面点和其他线路的自动分类&#xff1b;一键生成危险点报告和交跨报告&#xff1b;还能生成点云数据采集航线和自主巡检航线。 获取软件安装包联系邮箱:289…

ONLYOFFICE8.1版本桌面编辑器测评

OO官方链接点这里&#xff1a;ONLYOFFICE 文档 8.1 现已发布&#xff1a;功能全面的 PDF 编辑器、幻灯片版式、优化电子表格的协作等等 | ONLYOFFICE 博客 一、界面与用户体验 整体布局和设计的美观性、易用性&#xff1a; ONLYOFFICE 8.1 版本的桌面编辑器展现出了令人眼前一亮…

电路学习——经典运放电路(2024.06.21)

参考链接1: 11个经典运放电路 在此感谢各位前辈大佬的总结&#xff0c;写这个只是为了记录学习大佬资料的过程&#xff0c;内容基本都是搬运的大佬博客&#xff0c;觉着有用自己搞过来自己记一下&#xff0c;如果有大佬觉着我搬过来不好&#xff0c;联系我删。 电路学习——经典…

[职场] 公务员的利弊分析 #知识分享#经验分享#其他

公务员的利弊分析 公务员作为一种稳定的职业选择&#xff0c;一直备受人们的关注。然而&#xff0c;就像任何其他职业一样&#xff0c;公务员职位也有其利与弊。本文将对公务员的利弊进行分析&#xff0c;帮助读者更好地了解这一职业的特点。 利&#xff1a; 1. 稳定的职业&a…

【C++】文件处理(IO流)

文章目录 C IO流1. C语言IO2. CIO2.1 C标准IO流2.2 C文件IO流2.3 C IO 文件常用函数总结表2.4 C stringstream C IO流 回顾一下&#xff0c;C语言中IO输入输出的 1. C语言IO C语言中常用的输入输出函数有如下几种&#xff1a;前者是格式化标准输入输出&#xff0c;后者是格式化…

GD32 串口接受异常的几个原因

前面我们介绍过GD32 485发送时出现异常的最常见原因&#xff0c;有小伙伴反馈想要知道GD32 串口接受异常的可能原因&#xff0c;今天我们就来安排。 一、波特率异常导致收发出错 我们知道&#xff0c;串口是异步通讯接口&#xff0c;通讯双方或者多方都需要工作在相同波特率下…