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…...
为什么我们需要地图?
想一想,武侠小说里面。一张藏宝图,引来江湖腥风血雨,要么是武功秘籍,要么是绝世宝剑,要么是富可敌国的财富,只要有了藏宝图,便可曲径通幽,到达彼岸。 由此可见,地图的重…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
