Luggage Lock( The 2021 ICPC Asia Shenyang Regional Contest )

ops/2025/1/19 0:33:48/

Luggage Lock( The 2021 ICPC Asia Shenyang Regional Contest )

题面描述:

Eileen has a big luggage and she would pick a lot of things in the luggage every time when A-SOUL goes out for a show. However, if there are too many things in the luggage, the 4-digit password lock on the luggage will be hard to rotate.

The state of lock is the four digits on the lock. In one step, she can choose consecutive digits to rotate up by one simultaneously or down by one simultaneously. For example, she can rotate 0000 \texttt{0000} 0000 to 0111 \texttt{0111} 0111 or 0900 \texttt{0900} 0900 in one step because the rotated digits are consecutive, but she can’t rotate 0000 \texttt{0000} 0000 to 0101 \texttt{0101} 0101 in one step. Since she has little strength, she wants to rotate the lock as few times as possible.

Now the lock is at state a 0 a 1 a 2 a 3 a_0a_1a_2a_3 a0a1a2a3 and the password is b 0 b 1 b 2 b 3 b_0b_1b_2b_3 b0b1b2b3. As a fan of A-SOUL, you are asked to help Eileen find out the optimal plan to unlock but you only need to tell Eileen how many times she has to rotate.

input

The first line contains one integer T T T ( 1 ≤ T ≤ 1 0 5 ) (1 \leq T \leq 10^5) (1T105), denoting the numer of test cases.

Each of the test cases contains a line containing the initial state a 0 a 1 a 2 a 3 a_0a_1a_2a_3 a0a1a2a3 and the target state b 0 b 1 b 2 b 3 b_0b_1b_2b_3 b0b1b2b3.

output

For each test case, output a line containing a single integer, denoting the minimum steps needed to unlock.

Exemple
6
1234 2345
1234 0123
1234 2267
1234 3401
1234 1344
1234 2468
1
1
4
5
1
4

题目大意

Eileen有一个大行李箱,每次出门时她需要从行李箱中拿很多东西。然而,如果行李箱内放置的物品太多,四位数密码锁的旋转就会变得困难。

密码锁的状态是四个数字。在每一步中,Eileen可以选择连续的数字,将它们同时向上或向下旋转1。比如,她可以将0000旋转到01110900,但不能将0000旋转到0101,因为它们不是连续的数字。由于她力量有限,她希望以最少的步骤旋转密码锁。

现在,密码锁的状态是a0a1a2a3,目标密码是b0b1b2b3。作为A-SOUL的粉丝,你被要求帮助Eileen找出解锁的最优方案,但你只需要告诉Eileen需要多少步旋转才能解锁。


思路

这是一道很明显的bfs+模拟的题(和八数码是一类题)

其实可以采用离线,并且理解题目为从“0000”到目标状态的旋转次数!!!

比如说:“1234”到“2345”就相当于从“0000”到“1111”或者说“9999”

因为密码旋转本身就是环形结构,所以说可以一样操作。

因 为 起 点 和 终 点 都 不 一 样 , 还 有 1 e 5 个 测 试 样 例 。 因 此 不 能 直 接 对 每 一 组 样 例 都 做 一 遍 b f s , 肯 定 会 超 时 。 因为起点和终点都不一样,还有1e5个测试样例。因此不能直接对每一组样例都做一遍bfs,肯定会超时。因为起点和终点都不一样,还有1e5个测试样例。因此不能直接对每一组样例都做一遍bfs,肯定会超时。

因 此 我 们 可 以 将 所 有 测 试 样 例 的 起 点 都 转 化 为 0000 , 终 点 对 应 变 为 t [ i ] − s [ i ] ( s 为 起 点 , t 为 终 点 ) 因此我们可以将所有测试样例的起点都转化为0000,终点对应变为t[i]-s[i](s为起点,t为终点)因此我们可以将所有测试样例的起点都转化为0000,终点对应变为t[i]−s[i](s为起点,t为终点)

这 样 转 换 之 后 , 我 们 可 以 以 0000 作 为 起 点 进 行 一 遍 b f s , 同 时 记 录 下 到 达 每 个 状 态 所 需 的 步 数 。 这 样 对 于 这样转换之后,我们可以以0000作为起点进行一遍bfs,同时记录下到达每个状态所需的步数。这样对于这样转换之后,我们可以以0000作为起点进行一遍bfs,同时记录下到达每个状态所需的步数。这样对于每 个 测 试 样 例 即 可 O ( 1 ) 输 出 答 案 。 每个测试样例即可O(1)输出答案。每个测试样例即可O(1)输出答案。

代码实现

#include <map>
#include <set>
#include <fstream>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdio>
#include <bitset>
#include <iomanip>
#define endl '\n'
#define int long long
#define Max(a, b) (((a) > (b)) ? (a) : (b))
#define Min(a, b) (((a) < (b)) ? (a) : (b))
#define BoBoowen ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;const int inf = 1e9 + 7;
const int N = 2e5 + 10;
map<string, int> mp;void bfs(string s)
{string fir = "0000";queue<string> q;q.push(fir);mp[fir] = 0;while (!q.empty()){string now = q.front();q.pop();for (int i = 0; i < 4; ++i){int cz = 1;for (int k = 0; k < 2; ++k){cz *= -1;string nex = now;for (int j = 0; j + i < 4; ++j){nex[i + j] = (nex[i + j] - '0' + cz + 10) % 10 + '0';if (mp[nex] == 0 && nex != fir){// cout << nex << endl;mp[nex] = mp[now] + 1;q.push(nex);}}}}}
}void solved()
{string s1, s2;cin >> s1 >> s2;string s;for (int i = 0; i < 4; ++i){s += (s1[i] - s2[i] + 10) % 10 + '0';}// cout << s << endl;cout << mp[s] << endl;
}signed main()
{BoBoowen;bfs("0000");int T = 1;cin >> T;while (T--){solved();}
}

小小解读

  • mp 是一个 map,用来存储每个状态到达该状态的最小步数。
  • bfs 函数负责从初始状态 0000 开始进行广度优先搜索,计算到达每个状态的最小步数。
  • q 是一个队列,用来存储待探索的状态。
  • mp 存储每个状态的最小步数。初始时,将状态 0000 的步数设为 0。
  • 对于每个状态,尝试选择一个连续的子序列进行旋转操作。这里旋转有两种方式:顺时针(cz = 1)和逆时针(cz = -1)。
  • 每次旋转操作后,如果新的状态未被访问过,就将该状态加入队列并更新步数。
  • solved 函数负责处理每个测试用例。
  • 从输入中读取当前状态 s1 和目标状态 s2
  • 计算 s1s2 之间的差值,并转换成一个新的状态 s。这个差值表示需要旋转的步骤,(s1[i] - s2[i] + 10) % 10 保证了旋转结果始终在 0 到 9 之间。
  • 最后,输出该状态到达目标所需的最小步数,即 mp[s]
  • 主函数中,先调用 bfs("0000") 函数初始化所有从 0000 到其他状态的最小步数。
  • 然后通过循环处理每个测试用例。

总结

  • BFS 算法:用广度优先搜索遍历所有状态,确保找到从 0000 到目标状态的最小步数。
  • 状态转换:每次旋转一个连续的子序列,旋转方式有顺时针和逆时针。
  • 时间复杂度:由于 bfs 函数会遍历所有可能的状态,因此时间复杂度为 O(10^4),由于最多有 T 个测试用例,总的时间复杂度大约是 O(T * 10^4),对于 T = 10^5,每个测试用例的计算时间是常数时间,能够满足题目的要求。

http://www.ppmy.cn/ops/151225.html

相关文章

【FAQ】HarmonyOS SDK 闭源开放能力 —Map Kit(4)

1.问题描述&#xff1a; 添加了很多的marker点&#xff0c;每个marker点都设置了customInfoWindow&#xff0c;但是每次只能显示一个customInfoWindow吗&#xff1f; 解决方案&#xff1a; Marker的InfoWindow每次只能显示一个。 2.问题描述&#xff1a; 在地图选型中&…

Spring Boot中的配置文件有哪些类型

在 Spring Boot 中&#xff0c;配置文件用于管理应用程序的设置和参数&#xff0c;通常存放在项目的 src/main/resources 目录下。Spring Boot 支持多种类型的配置文件&#xff0c;并通过这些文件来控制应用的行为和环境配置。 1. application.properties application.proper…

Spring Boot中的Profile是如何工作

在 Spring Boot 中&#xff0c;Profile 是一种用于区分不同环境配置的机制&#xff0c;它允许开发者为不同的环境&#xff08;如开发、测试、生产等&#xff09;提供不同的配置。这是通过 Profile 注解以及相关的配置文件实现的。通过使用 Profile&#xff0c;Spring Boot 可以…

C# 并发和并行的区别--16

目录 并发和并行 一.并发 定义 特点 代码示例 代码解释 二.并行 定义 特点 在C#中的体现 代码示例 代码解释 三.并发和并行的区别 四 .如何在C#中选择并发还是并行 1.考虑任务类型 2.代码示例 3.注意事项 五.总结 并发和并行 在编程领域,并发和并行是两个密切…

CSS布局与响应式

学习链接 Grid网格布局 前端五大主流网页布局 flex布局看这一篇就够了 grid布局看这一篇就够了 用六个案例学会响应式布局 伸缩盒响应式页面布局实战 实现响应式布局的五种方式 - csdn 如何完成响应式布局&#xff0c;有几种方法&#xff1f;看这个就够了 响应式布局总…

利用.NET版Word处理控件Aspose.Words,使用 C# 在 Word 中创建图表

Microsoft Word 中的图表使数据可视化变得简单而有效。它们将数字转换为视觉效果&#xff0c;帮助您的内容脱颖而出。您可以直接在 Word 中创建图表来说明趋势、比较等。从条形图、饼图、折线图和其他样式中进行选择&#xff0c;以满足您的需求。Microsoft Word 具有用于创建图…

解决 vxe-table 的下拉框、日期选择等组件被 element-plus element-ui 弹窗遮挡问题 z-index

官网文档&#xff1a;https://vxetable.cn 解决 vxe-table 的下拉框、日期选择等组件被 element-plus element-ui 弹窗遮挡问题 z-index 通过官方文档说明的全局参数设置一下就可以了&#xff1a; import { VxeUI } from vxe-table // 任意一种方式都行 // import { VxeUI }…

解决conda create速度过慢的问题

问题 构建了docker容器 想在容器中创建conda环境&#xff0c;但是conda create的时候速度一直很慢 解决办法 宿主机安装的是anaconda 能正常conda create,容器里安装的是miniforge conda create的时候速度一直很慢&#xff0c;因为容器和宿主机共享网络了&#xff0c;宿主机…