UVa 1343 The Rotation Game 旋转游戏 IDA* BFS 路径还原
题目链接:The Rotation Game
题目描述:
给定二十四个整数,这二十四个整数由八个一,八个二,八个三组成,从左到右,从上到下依次描述下图方格中的数字:
例如上图左边对应的输入就是[1,1,1,1,3,2,3,2,3,1,3,2,2,3,1,2,2,2,3,1,2,1,3,3][1, 1, 1, 1, 3, 2, 3, 2, 3, 1, 3, 2, 2, 3, 1, 2, 2, 2, 3, 1, 2, 1, 3, 3][1,1,1,1,3,2,3,2,3,1,3,2,2,3,1,2,2,2,3,1,2,1,3,3]。你每一次可以进行A−HA-HA−H八种操作,上图给出了AAA操作和CCC操作如何进行,其他的操作如何进行可以类似的推出,你的任务是找到最少的操作步数让中间的八个数字为同一个数字,例如上图左边经过两次操作能将中间全部变成222,如果有多个解,那么你需要输出字典序最小的解,同时你还需要输出中间的数字。
题解:
本题可以使用IDA∗(IterativeDeepeningAStar)IDA*(Iterative Deepening A Star)IDA∗(IterativeDeepeningAStar)算法,直接依次枚举进行的操作(需要注意的是,应该先枚举字典序小的),很明显可以发现,每一次移动最多只会让中间的位置正确的数字个数增加一,所以可以考虑的剪枝是:最大深度与当前深度之差如果小于中间最少的不对的数字时进行剪枝。
当然本题还有其他的做法。
本题也可以通过BFSBFSBFS来做,不过使用BFSBFSBFS来解决本题的时候,我们可以转换一下思路,我们可以把目标状态能够到达的所有其他状态枚举出来,这样的花费与从某个状态到目标状态是一样的。但是这样枚举存在一个问题:时间复杂度过高。
时间复杂度如何计算?要计算时间复杂度也就是计算所有可能的状态,也就是计算242424个数字,这242424个数字含有三种数字,每种数字的个数均为888的排列个数,那么根据高中的组合数学知识,我们可以知道可能的排列个数为24!8!8!8!\frac {24!} {8!8!8!}8!8!8!24!,这个数字是比较大的。不过我们有新的方法,因为只需要中间的八个数字相同,我们可以依次枚举中间可能的数字(这里是1,2,31, 2, 31,2,3),不同于中间可能的数字记为000,这样可能状态数量就变成了242424个数字包含两种数字,其中一种数字的个数是888,另一个种数字的个数是161616的排列个数,那么此时的排列个数变成了24!8!16!\frac {24!} {8!16!}8!16!24!此时的复杂度就到了可以接受的范围了。我们在BFSBFSBFS完成之后可以不用存储每一次的路径,而是在后续来还原出路径,这样可以节省一定的空间开销,还原的过程类似于BFSBFSBFS的过程,只是还原的时候只会访问最佳的路径,而不是所有的路径。同时在BFSBFSBFS的时候,由于在队列中放入一个数组非常不好处理,所以我们需要将状态进行编码,由于一共只有242424个状态,那么我们可以用242424位的二进制数来表示每一个位置的状态。
经过测试IDA∗IDA*IDA∗速度要快得多。
IDA*代码:
#include <bits/stdc++.h>using namespace std;int g[24];
vector<char> ans;// 数据的下标 6 7 8 11 12 15 16 17为中间的八个数字
// 返回最少需要几个数字让中间八个数字相同
int getWrongPos()
{int cnt[4] = {0};cnt[g[6]]++;cnt[g[7]]++;cnt[g[8]]++;cnt[g[11]]++;cnt[g[12]]++;cnt[g[15]]++;cnt[g[16]]++;cnt[g[17]]++;return 8 - max(cnt[1], max(cnt[2], cnt[3]));
}void move(int op)
{int temp = 0;switch(op) {case 0:temp = g[0];g[0] = g[2];g[2] = g[6];g[6] = g[11];g[11] = g[15];g[15] = g[20];g[20] = g[22];g[22] = temp;break;case 1:temp = g[1];g[1] = g[3];g[3] = g[8];g[8] = g[12];g[12] = g[17];g[17] = g[21];g[21] = g[23];g[23] = temp;break;case 2:temp = g[10];for (int i = 10; i >= 5; i--) { g[i] = g[i - 1]; }g[4] = temp;break;case 3:temp = g[19];for (int i = 19; i >= 14; i--) { g[i] = g[i - 1]; }g[13] = temp;break;case 4:temp = g[23];g[23] = g[21];g[21] = g[17];g[17] = g[12];g[12] = g[8];g[8] = g[3];g[3] = g[1];g[1] = temp;break;case 5:temp = g[22];g[22] = g[20];g[20] = g[15];g[15] = g[11];g[11] = g[6];g[6] = g[2];g[2] = g[0];g[0] = temp;break;case 6:temp = g[13];for (int i = 13; i <= 18; i++) { g[i] = g[i + 1]; }g[19] = temp;break;case 7:temp = g[4];for (int i = 4; i <= 9; i++) { g[i] = g[i + 1]; }g[10] = temp;break;default:return;}
}void undoMove(int op)
{if (op % 2 == 0) { move((op + 5) % 8); }else { move((op + 3) % 8); }
}bool dfs(int nowDepth, int maxDepth)
{int wrongPos = getWrongPos();if (nowDepth == maxDepth) { return wrongPos == 0; }if (maxDepth - nowDepth < wrongPos) { return false; }for (int i = 0; i < 8; i++) { // 要求字典序最小只需要从小到大枚举即可ans.push_back(i + 'A');move(i);if (dfs(nowDepth + 1, maxDepth)) { return true; }undoMove(i);ans.pop_back();}return false;
}int main()
{ios::sync_with_stdio(false);while (cin >> g[0] && g[0] != 0) {for (int i = 1; i < 24; i++) { cin >> g[i]; }ans.resize(0);for (int maxDepth = 0; ; maxDepth++) {if (dfs(0, maxDepth)) {if (maxDepth == 0) {cout << "No moves needed" << endl << g[6] << endl;} else {for (auto ch : ans) { cout << ch; }cout << endl << g[6] << endl;}break;}}}return 0;
}
BFS代码:
#include <bits/stdc++.h>const int INF = 0x3f3f3f3f;using namespace std;int g[24];
int finalStatus[] = {0, 0,0, 0,0, 0, 1, 1, 1, 0, 0,1, 1,0, 0, 1, 1, 1, 0, 0,0, 0,0, 0};
int finalStatusEncode, ansDis, ans;
map<int, int> dis;
string ansStr; // 这里改成string可以方便的比较大小int encode(int *status, int number)
{int statusEncode = 0;for (int i = 0; i < 24; i++) { statusEncode |= (status[i] == number ? (1 << i) : 0); }return statusEncode;
}void decode(int statusEncode, int *status)
{for (int i = 0; i < 24; i++) { status[i] = (statusEncode & (1 << i)) >> i; }
}void move(int op, int *g); //该函数与IDA*中一样,这里不再给出void bfs()
{finalStatusEncode = encode(finalStatus, 1);queue<int> q;q.push(finalStatusEncode);dis[finalStatusEncode] = 0;while(!q.empty()) {int nowStatus = q.front();q.pop();for (int i = 0; i < 8; i++) {decode(nowStatus, g); // 先解码,解码的目的是为了进行移动操作move(i, g);int newStatus = encode(g, 1);if (dis.count(newStatus) == 0) {dis[newStatus] = dis[nowStatus] + 1;q.push(newStatus);}}}
}void getPath()
{int gTemp[24] = {0};for (int number = 1; number <= 3; number++) {int nowStatus = encode(g, number);if (ansDis == dis[nowStatus]) {string nowStr;while (nowStatus != finalStatusEncode) {for (int i = 0; i < 8; i++) {decode(nowStatus, gTemp);move(i, gTemp);int newStatus = encode(gTemp, 1);if (dis.count(newStatus) == 1 && dis[newStatus] + 1 == dis[nowStatus]) { // 在最短路径上nowStatus = newStatus;nowStr.push_back(i + 'A');break;}}}if (nowStr < ansStr) {ansStr = nowStr;ans = number;}}}
}int main()
{ios::sync_with_stdio(false);bfs();while (cin >> g[0] && g[0] != 0) {for (int i = 1; i < 24; i++) { cin >> g[i]; }ansDis = INF;ansStr = "Z"; // "Z"比所有可能的答案的字典序都要大for (int number = 1; number <= 3; number++) { // 分别枚举中间的数字int status = encode(g, number);ansDis = min(ansDis, dis[status]); // 题目一定是有解的}if (ansDis == 0) {cout << "No moves needed" << endl << g[6] << endl;} else {getPath();cout << ansStr << endl << ans << endl;}}return 0;
}
相关文章:
UVa 1343 The Rotation Game 旋转游戏 IDA* BFS 路径还原
题目链接:The Rotation Game 题目描述: 给定二十四个整数,这二十四个整数由八个一,八个二,八个三组成,从左到右,从上到下依次描述下图方格中的数字: 例如上图左边对应的输入就是[1,…...
硬件学习 软件Cadence day02 画原理图的基本操作 (键盘快捷键 , 原理图设计流程 , 从开始到导出网表流程)
1. ORCAD Capture cls 界面的快捷键 键盘 按键对应的操作I放大 (可以滚轮操作)O缩小 (可以滚轮操作)W画线Esc退出现在的状态 (画图界面 右键 End xxx)N放置网络标号J放置节点 (控制…...
【python】基于Socket的聊天室Python开发
基于Socket的聊天室Python开发一、Socket简述二、创建服务端Server2.1 创建服务端初始化2.2 监听客户端连接2.3 处理客户端消息三、创建客户端Client3.1 创建服务端初始化3.2 发送消息3.3 接收消息3.3 线程工作3.4 线程工作是不是挺好玩的呢?也可以作为课程设计哦&a…...
2023想转行软件测试的看过来,你想要了解的薪资、前景、岗位方向、学习路线都讲明白了
在过去的一年中,软件测试行业发展迅速,随着数字化技术应用的广泛普及,业界对于软件测试的要求也在持续迭代与增加。 同样的,有市场就有需求,软件测试逐渐成为企业中不可或缺的岗位,作为一个高薪又需求广的…...
TortoiseSVN的使用
基本概念 版本库 SVN保持数据的地方,所有的文件都保存在这个库中,Tortoise访问的就是远程服务器上的Subversion版本库。 工作拷贝 就是工作副本,可将版本库的文件拷贝到本地中,可以任意修改, 不会影响版本库。在你…...
操作系统(day09) -- 连续分配管理方式
连续分配管理方式 单元连续分配 动态分区分配 1.系统要用什么样的数据结构记录内存的使用情况? 两种常用的数据结构 空闲分区表 每个空闲分区对应一个表项。表项中包含分区号、分区大小、分区起始地址等信息空闲分区链 每个分区的起始部分和末尾部分分别设置前向…...
APISpace 带你一起走进西湖美景
俗话说:“上有天堂,下有苏杭”。 “欲把西湖比西子,浓妆艳抹总相宜” 今天我就带大家走进杭州的西湖美景。自古以来,文人歌者面对西湖美景留下千古绝句,还以西湖为背景书写了一段段动人的爱情传说。 天生自带浪漫色…...
傻白探索Chiplet,Design Space Exploration for Chiplet-Assembly-Based Processors(十三)
阅读了Design Space Exploration for Chiplet-Assembly-Based Processors这篇论文,是关于chiplet设计空间探索的,个人感觉核心贡献有两个:1.提出使用整数线性规划算法进行Chiplet的选择;2.基于RE和NRE提出了一个cost模型ÿ…...
系统分析师真题2020试卷相关概念一
对象系统测试的基本概念: 面向对象系统的单元测试包括方法层次的测试、类层次的测试和类树层次的测试。方法层次的测试类似于传统软件测试中对单个函数的测试; 测试技术: 方法层次的测试,单个函数的测试;常用的技术:等价类划分测试、组合功能测试、递归函数的测试和多态…...
20230215_数据库过程_渠道业务计算过程
—20221209 渠道产能 —自有人员工号表 shzc.xc_qdcn_pgtx_opertype —select * from shzc.xc_qdcn_pgtx_opertype for update ; —渠道基础目录 shzc.xc_qdcn_pgtx_qdtype —select * from shzc.xc_qdcn_pgtx_qdtype for update ; SQL_STRING:‘update shzc.xc_qdcn_pgtx_q…...
【C++】Expression的学习笔记
关于不同类别表达式的举例,请参考博文《C 中的值类别》 1. 左值和右值的简单理解 左值对应了具有内存地址的对象,而右值仅仅是临时使用的值对象。(引用自博文《C 中的值类别》)左值有名称(变量或常量名称)…...
[数据库迁移]-MySQL常见问题
[数据库迁移]-MySQL常见问题 森格 | 2023年2月 介绍:记录在MySQL数据库迁移过程中遇到的问题,以及解决方案。 文章目录[数据库迁移]-MySQL常见问题一、背景二、常见问题2.1 ERROR 20032.2 ERROR 12732.3 ERROR 10712.4 视图权限2.5 ERROR 1062三、总结一…...
C语言编译过程
C语言编译过程1、C语言编译过程2、单c文件编译实践3、多c文件编译实践4、define4.1、不带参宏4.2、带参宏4.3、带参宏和带参函数的区别5、选择性编译ifdef、ifndef、if5.1、#ifdef5.2、#ifndef5.3、#if6、静态库和动态链接库6.1、静态库实践6.1.1、将mylib.c制作成静态库6.1.2、…...
前端学习 ---常用标签
常用标签 1,文本标签 文本标签是双标签,自带加粗效果,有自己对应的文本大小,并且独占一行,有默认间距 一级标签:< h1 > < /h1 > 二级标签:< h2 > < /h2> 三级标签:&l…...
2023年PMP考试难不难?
整个考试的考察方向转向还是比较大的,基本上以“价值传递”和“以人为本”这两个出发点来考察项目经理所需要的能力。 1}新版提纲题目数量的变化 总题量从200道减少到180道,所以答题时间上相对变的宽裕一些。考试时间230分钟,中间有十分钟休…...
Netty 入门
文章目录一、概述1.1 Netty 是什么?1.2 Netty 的地位1.3 Netty 的优势二、Hello World2.1 目标2.2 服务器端2.3 客户端2.4 流程梳理三、组件3.1 EventLoop3.2 演示 NioEventLoop 处理 io 事件3.3 演示 NioEventLoop 处理普通任务3.4 演示 NioEventLoop 处理定时任务…...
收藏|一文掌握数据分析在企业的实际流程
一、数据分析概念 1.1 数据分析 是指用适当的统计分析方法对收集来的大量数据进行分析,将他们加以汇总和理解并消化,以求最大化地开发数据的功能,发挥数据的作用。 1.2 数据分析包括 描述性数据分析(初级数据分析)…...
100ask_imx6ull 输出PWM
查看PWM对应扩展板的引脚 100ask_imx6ul通过扩展板插槽来验证pwm波,所以这里通过扩展板的原理图及芯片手册可知,gpio4_io20,gpio4_io19分别对应着PWM8和PWM7。 设置设备树 打开官方NXP的工具i.MX pins v6工具,PWM7/PWM8的配置如…...
yolov5编译安卓APP:解决图像上全是检测框
yolov5编译安卓APP:解决图像上全是检测框前言一、第一个YOLOv5 APP1.参考链接2.详细说明3.APP检测时图像上全是框的解决方法二、第二个YOLOv5 APP1.参考链接2.详细说明3.APP检测时图像上全是框的解决方法三、其他1.APK打包2.修改APP图标与名字前言 YOLOv5编译安卓A…...
为什么我们需要地图?
想一想,武侠小说里面。一张藏宝图,引来江湖腥风血雨,要么是武功秘籍,要么是绝世宝剑,要么是富可敌国的财富,只要有了藏宝图,便可曲径通幽,到达彼岸。 由此可见,地图的重…...
攻防世界1.新手练习区
4.攻防世界1.新手练习区 1.view_source 访问url: http://111.200.241.244:48855/ 鼠标点击右键不起作用,F12审查元素 得到flag为cyberpeace{0f3a3e4ab8c8664f3cf40d4240ec7b53} 2.robots 访问url: http://111.200.241.244:34362/ rob…...
Python进阶篇(二)-- Django 深入模型
上一节提到了Django是基于MVC架构的Web框架,MVC架构追求的是“模型”和“视图”的解耦合。所谓“模型”说得更直白一些就是数据(的表示),所以通常也被称作“数据模型”。在实际的项目中,数据模型通常通过数据库实现持久…...
ABAP SALV实现弹出ALV选择
问题场景 需要弹出一个ALV并获取选择的数据 实现思路 跳转屏幕弹出ALV(通过SALV)弹出ALV(通过REUSE_ALV_POPUP_TO_SELECT) 实现效果 因为这里需要的是单选,所以没有多选列 实现代码 MODULE sel_zfretype INPUT.…...
git check-pick,git patch 与 git stash 详解
大家好,我是 17。 今天和大家聊一聊 git check-pick,git patch 与 git stash 的用法。 git cherry-pick 为什么要用 cherry-pick? 不适合 merge 的场景就可以考虑 cherry-pick。 试想下面这些场景 只想同步分支的部分提交。两个分支是两上完全独立…...
OA漏洞-到处搜集整理
一米OA getfile.jsp 任意文件读取漏洞 原文链接 漏洞复现 一米OA getfile.jsp 任意文件读取漏洞 一米OA协同办公系统,集成了OA办公自动化系统、手机客户端、专业报表工具,为全国千万企业用户提供全功能、性价比高的OA软件。一米OA getfile.jsp文件存在任意文件读取漏洞&am…...
web端接收读卡器卡片信息
项目背景 通过电脑连接的读卡器读取卡片信息,并由web页面接收和处理卡片信息。 读卡器抛出卡片信息流程 卡片贴近或放置到读卡器上读卡器解析卡片信息,并形成固定格式的字符串,包括的信息有:卡片写入的数据、卡片原数据&#x…...
BUUCTF-练习场-WEB-第一部分(8道)
[极客大挑战 2019]EasySQL 1payload:1 or 11#是闭合前面的查询语句,or 11恒成立,可以使用or句子绕过判断,#用于注释,注释后面的内容不再执行,所以该sql命令会返回表内所有内容,其实就是实现一个…...
Java Reflection 实战- Class类
Java Reflection 实战 - Class Java 反射使得在运行时检查类、接口、字段和方法成为可能,而不需要在编译时知道类、方法等的名称。也可以使用反射来实例化新对象、调用方法和获取/设置字段值。 Java反射的功能相当强大,可以说是非常有用。例如ÿ…...
背包问题理解思路(01背包、完全背包、分组背包)
这两天把经典的三个背包问题看了一下,网上大多文章是以代码和公式为主,因为平时没刷过算法题所以理解起来花了些时间,固写一篇文章记录理解思路,本文不包含代码实现(理解了思路代码实现应该是小问题,网上一…...
Mr. Cappuccino的第39杯咖啡——Kubernetes之深入理解Pod
Kubernetes之深入理解PodPod相关概念Pod详细配置清单Pod核心配置Pod基本配置1. 创建yaml文件2. 创建namespace并根据yaml文件创建资源3. 查看namespace下的pod列表以及pod的详细信息Pod中多个容器的名称和端口号不能相同Pod镜像拉取策略Pod环境变量Pod端口相关设置Pod资源相关配…...
dede织梦建站教程/seo网站设计工具
万拓超融合存储CS100-48是万拓推出的新一代48盘位云节点产品,凭借12G高性能背板、支持硬盘防震、大风量散热、嵌入式BBU、支持通用主板这些优点,很好地满足了中大型超融合系统和云存储系统的需求,产品广泛适用于公安、运营商、交通、政府、教…...
导购网站怎么做视频教学/品牌运营策划
一、画线 只有在drawRect中才能获取到跟view相关联的上下文 - (void)drawRect:(CGRect)rect {} 一条线 // 1.获取跟当前View相关联的layer上下文(画板)// 总结:目前获取的所有上下文都是以UIGraphics开头// CGContextRef:上下文类型// CG:CoreGraphics Ref:引用CGContextRef ct…...
申请一个域名多少钱/wordpress seo教程
AVCodecContext AVCodecContext 结构表示程序运行的当前 Codec 使用的上下文,着重于所有 Codec 共有的属性(并且是在程序运行时才能确定其值)和关联其他结构的字段。extradata 和 extradata_size 两个成员表述了相应 Codec 使用的私有数据;codec成员关联…...
php网站链接支付宝/怎样在网上做宣传
<!--实现搜索结果的关键词变色标注的程序四月 5th, 2006 在搜索得到的文本中,从第一个关键词出现的前50个字开始显示,把关键词替换为红色,这比单纯的用replace得到的显示结果更人性化一些,因为用replace的话一旦关键词出现在文…...
做室内设计兼职的网站/软文写作的十大技巧
一、问题现象某客户有一台安装RHEL6.5系统的服务器,该服务器需要配置内网和外网两个IP地址,系统配置好IP地址重启网卡服务后,通过内、外网IP地址都能正常连接。过一会儿后就连接不正常了,该服务器无法通过外网IP地址远程连接&…...