2022-10-25:在一个 2 * 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字(上下左右)进行交换.
2022-10-25:在一个 2 * 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示,
以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字(上下左右)进行交换.
最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。
给出一个谜板的初始状态 board ,
返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。
输入:board = [[1,2,3],[4,0,5]]。
输出:1。
答案2022-10-25:
力扣773。A*算法,曼哈顿距离。
经过测试,rust的运行速度和内存占用都是最优的,go次之,java再次之。c++运行速度比java还慢了。
这道题可以用穷举打表法。
代码用rust编写。代码如下:
use std::collections::HashSet;
impl Solution {
pub fn sliding_puzzle(m: Vec<Vec<i32>>) -> i32 {
unsafe {
nexts = vec![0, 0, 0];
let mut set: HashSet<i32> = HashSet::new();
let from =
m[0][0] * b6 + m[0][1] * b5 + m[0][2] * b4 + m[1][0] * b3 + m[1][1] * b2 + m[1][2];
let mut heap = Vec::new();
// [
// 从from出发到达当前状态,已经走了几步,
// 从当前状态到最终状态的估计距离
// 当前状态是什么,用数字代表
// ]
heap.push(vec![0, Solution::distance(from), from]);
let mut ans = -1;
while heap.len() > 0 {
heap.sort_by(|a, b| (b[0] + b[1]).cmp(&(a[0] + a[1])));
let arr = heap.pop().unwrap();
let distance = arr[0];
let cur = arr[2];
if set.contains(&cur) {
continue;
}
if cur == 123450 {
ans = distance;
break;
}
set.insert(cur);
let next_size = Solution::nexts(cur);
for i in 0..next_size {
let next = nexts[i as usize];
if !set.contains(&next) {
heap.push(vec![distance + 1, Solution::distance(next), next]);
}
}
}
return ans;
}
}
unsafe fn nexts(from: i32) -> i32 {
// 301245
// 10000
// a = 3
let a = from / b6;
// b = 0
let b = (from / b5) % 10;
// c = 1
let c = (from / b4) % 10;
// d = 2
let d = (from / b3) % 10;
// e = 4
let e = (from / b2) % 10;
// f = 5
let f = from % 10;
if a == 0 {
nexts[0] = from + (b - a) * b6 + (a - b) * b5;
nexts[1] = from + (d - a) * b6 + (a - d) * b3;
return 2;
} else if b == 0 {
nexts[0] = from + (a - b) * b5 + (b - a) * b6;
nexts[1] = from + (c - b) * b5 + (b - c) * b4;
nexts[2] = from + (e - b) * b5 + (b - e) * b2;
return 3;
} else if c == 0 {
nexts[0] = from + (b - c) * b4 + (c - b) * b5;
nexts[1] = from + (f - c) * b4 + (c - f);
return 2;
} else if d == 0 {
nexts[0] = from + (a - d) * b3 + (d - a) * b6;
nexts[1] = from + (e - d) * b3 + (d - e) * b2;
return 2;
} else if e == 0 {
nexts[0] = from + (b - e) * b2 + (e - b) * b5;
nexts[1] = from + (d - e) * b2 + (e - d) * b3;
nexts[2] = from + (f - e) * b2 + (e - f);
return 3;
} else {
nexts[0] = from + (e - f) + (f - e) * b2;
nexts[1] = from + (c - f) + (f - c) * b4;
return 2;
}
}
// 当前的数,num
// 最终要去的数,123450
// 返回num -> 123450 曼哈顿距离!
fn distance(num: i32) -> i32 {
let a = -1;
let b = i32::abs(a);
let mut ans = end[(num / b6) as usize][0] + end[(num / b6) as usize][1];
ans +=
end[((num / b5) % 10) as usize][0] + i32::abs(end[((num / b5) % 10) as usize][1] - 1);
ans +=
end[((num / b4) % 10) as usize][0] + i32::abs(end[((num / b4) % 10) as usize][1] - 2);
ans +=
i32::abs(end[((num / b3) % 10) as usize][0] - 1) + end[((num / b3) % 10) as usize][1];
ans += i32::abs(end[((num / b2) % 10) as usize][0] - 1)
+ i32::abs(end[((num / b2) % 10) as usize][1] - 1);
ans +=
i32::abs(end[(num % 10) as usize][0] - 1) + i32::abs(end[(num % 10) as usize][1] - 2);
return ans;
}
}
const b6: i32 = 100000;
const b5: i32 = 10000;
const b4: i32 = 1000;
const b3: i32 = 100;
const b2: i32 = 10;
static mut nexts: Vec<i32> = vec![];
const end: [[i32; 2]; 6] = [[1, 2], [0, 0], [0, 1], [0, 2], [1, 0], [1, 1]];
fn main() {
let nums = vec![vec![1, 2, 3], vec![4, 0, 5]];
let ans = Solution::sliding_puzzle(nums);
println!("ans = {:?}", ans);
}
struct Solution {}
执行结果如下:
2022-10-25:在一个 2 * 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字(上下左右)进行交换.的更多相关文章
- dmalloc在嵌入式的开发板上的应用
下面是我实际在开发环境里面做的dmalloc移植时候的一些随笔 配置PC的dmalloc环境1. 首先把源码包打开,进入dmalloc文件夹2. ./configure 配置Makefile,我是加了 ...
- 10.25 正睿停课训练 Day9
目录 2018.10.25 正睿停课训练 Day9 A 数独(思路 DP) B 红绿灯(最短路Dijkstra) C 轰炸(计算几何 圆并) 考试代码 B C 2018.10.25 正睿停课训练 Da ...
- 【剑指offer】找出数组中任意一个重复的数字,C++实现
原创博文,转载请注明出处! # 题目 # 思路 对于长度为n的数组,范围为0~n-1的数字而言,如果不粗在重复数字,则排序后数组元素和数组角标相同.如果存在重复数字,则在排序的过程中会出现不同下标对应 ...
- 最后一个非零数字(POJ 1604、POJ 1150、POJ 3406)
POJ中有些问题给出了一个长数字序列(即序列中的数字非常多),这个长数字序列的生成有一定的规律,要求求出这个长数字序列中某个位上的数字是多少.这种问题通过分析,找出规律就容易解决. 例如,N!是一个非 ...
- 背水一战 Windows 10 (25) - MVVM: 通过 x:Bind 实现 MVVM(不用 Command)
[源码下载] 背水一战 Windows 10 (25) - MVVM: 通过 x:Bind 实现 MVVM(不用 Command) 作者:webabcd 介绍背水一战 Windows 10 之 MVV ...
- FS210开发板上Qt4.7.0移植过程
作者:冯老师,华清远见嵌入式学院讲师. 1. 搭建Qt开发环境平台 1.开发环境:ubuntu 12.04 2.交叉编译链:arm-cortex_a8-linux-gnueabi 3.开发板:FS21 ...
- 小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和
小易邀请你玩一个数字游戏,小易给你一系列的整数.你们俩使用这些整数玩游戏.每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字. 例如: 如果{2,1,2 ...
- CentOS安装NodeJS v0.10.25 + Express
安装必需组件 yum -y install gcc make gcc-c++ openssl-devel wget cd ~wget http://nodejs.org/dist/v0.10.25/n ...
- 华为 2015 机试 输出:数字后面的连续出现的(2个或多个)相同字符(数字或者字符),删去一个,非数字后面的不要删除,例如,对应输出为:33aabb55pin。
package 华为机试; //C++ 输入:由数字和字母组成的字符串,例如:333aaabb55ppin //输出:数字后面的连续出现的(2个或多个)相同字符(数字或者字符),删去一个,非数字后面的 ...
- java语言将任意一个十进制数数字转换为二进制形式,并输出转换后的结果
package com.llh.demo; import java.util.Scanner; /** * * @author llh * */ public class Test { /* * 将任 ...
随机推荐
- Qt 5.15.2 QTextEdit无法设置新字体的处理方式
首发于我的个人博客:xie-kang.com 博客内有更多文章,欢迎大家访问 原文地址 在使用QT 5.15.2 开发的过程中碰到了件怪事,下列代码无法给QTextEdit选中的文字设置字体: QTe ...
- HAL层分析
1. 安卓HAL模块基本 2. 定义hal层代码的5个特性 1)硬件抽象层具有与硬件的密切相关性. 2) 硬件抽象层具有与操作系统无关性. 3) 接口定义的功能应该包含硬件或者系统所需硬件支持的所有功 ...
- SpringBoot笔记--配置文件分类+yaml相关知识+读取配置文件内容
配置文件 要是需要使用自己的配置替换默认配置时,需要使用后缀名为application.properties或者application.yml(application.yaml)进行配置 当然,几个文 ...
- Linux0.11源码学习(三)
Linux0.11源码学习(三) linux0.11源码学习笔记 参考资料: https://github.com/sunym1993/flash-linux0.11-talk https://git ...
- 多路复用IO:select poll epoll
[电话面试]io多路复用专题面试 这个真猛 有人做了笔记:点这里 select Select(Max+1,&rset,null,null,null)是因为0~max是max+1. 过程: 将文 ...
- 再谈回声消除测评丨Dev for Dev 专栏
本文为「Dev for Dev 专栏」系列内容,作者为声网音视频实验室工程师 黄译庆. 音频质量的优化是一个复杂的系统工程,回声消除是其中一个老生常谈的话题,一般来说,回声消除的效果受设备本身的声学设 ...
- 声网Agora 实时音视频服务正式上线 HTC VIVE Sync App,支持非 VR 用户
全球实时互动云服务开创者和引领者声网Agora(纳斯达克股票代码:API)宣布其视频 SDK 现已集成到领先的 VR/XR 远程协作及会议应用 HTC VIVE Sync App 中. 通过集成声网A ...
- Linux文件上传下载--rz/sz命令
原文地址:https://www.cnblogs.com/igoodful/p/14694038.html 1.rz 命令 1.1 命令简介 rz 命令(Receive ZMODEM),使用 ZMOD ...
- Hyper-V由于虚拟机监控程序未运行
以管理员权限打开命令提示符 输入bcdedit /set hypervisorlaunchtype Auto 重启计算机
- 动态求前n个最小值(最大值)
注: 由于最小值和最大值的分析过程完全相同,这里我们只讨论最小值的分析流程,最大值同理 问题描述 每次给定一个数值,询问此数值以及之前给定数值中最小的n个数 例如给定数值的顺序为:8 7 1 2 9 ...