2023-08-16:用go写算法。一个坐标可以从 -infinity 延伸到 +infinity 的 无限大的 棋盘上,

你的 骑士 驻扎在坐标为 [0, 0] 的方格里。

骑士的走法和中国象棋中的马相似,走 “日” 字:

即先向左(或右)走 1 格,再向上(或下)走 2 格,

或先向左(或右)走 2 格,再向上(或下)走 1 格,

每次移动,他都可以像中国象棋中的马一样,选八个方向中的一个前进。

返回 骑士前去征服坐标为 [x, y] 的部落所需的最小移动次数。

本题确保答案是一定存在的。

输入:x = 2, y = 1。

输出:1。

解释:[0, 0] → [2, 1]。

输入:x = 5, y = 5。

输出:4。

解释:[0, 0] → [2, 1] → [4, 2] → [3, 4] → [5, 5]。

提示:|x| + |y| <= 300。

来自Indeed、谷歌、亚马逊、领英、英伟达。

来自左程云

答案2023-08-16:

大体步骤如下:

1.初始化一个二叉堆(binary heap)和一个哈希表(hashmap)用于存储已访问的位置。

2.将起始位置 [0, 0] 添加到二叉堆中,并初始化最小移动次数为无穷大。

3.进入循环,直到二叉堆为空:

  • 弹出堆顶位置,获取当前位置的代价、行号和列号。

  • 检查当前位置是否已经访问过,如果是则跳过该位置。

  • 检查当前位置是否达到目标位置,如果是则更新最小移动次数为当前代价,并结束循环。

  • 标记当前位置为已访问。

  • 尝试向八个方向移动,将可行的新位置添加到二叉堆中。

4.返回最小移动次数。

总的时间复杂度:在最坏情况下,需要访问所有格子,每次访问需要将新位置添加到二叉堆中,时间复杂度为O(N log N),其中N是需要访问的格子数量。

总的额外空间复杂度:使用了二叉堆和哈希表来存储已访问的位置,额外空间复杂度为O(N),其中N是需要访问的格子数量。

go完整代码如下:

package main

import (
"fmt"
"math" "github.com/emirpasic/gods/maps/hashmap"
"github.com/emirpasic/gods/sets/hashset"
"github.com/emirpasic/gods/trees/binaryheap"
) // minKnightMoves calculates the minimum number of moves required for a knight to reach position (x, y).
func minKnightMoves(x, y int) int {
heap := binaryheap.NewWith(func(a, b interface{}) int {
return int(a.([]int)[0] + a.([]int)[1] - b.([]int)[0] - b.([]int)[1])
})
closed := hashmap.New()
heap.Push([]int{0, distance(0, 0, x, y), 0, 0})
ans := math.MaxInt32 for heap.Size() > 0 {
c, _ := heap.Pop()
cur := c.([]int)
cost := cur[0]
row := cur[2]
col := cur[3] if isClosed(closed, row, col) {
continue
} if row == x && col == y {
ans = cost
break
} close(closed, row, col)
add(cost+1, row+2, col+1, x, y, closed, heap)
add(cost+1, row+1, col+2, x, y, closed, heap)
add(cost+1, row-1, col+2, x, y, closed, heap)
add(cost+1, row-2, col+1, x, y, closed, heap)
add(cost+1, row-2, col-1, x, y, closed, heap)
add(cost+1, row-1, col-2, x, y, closed, heap)
add(cost+1, row+1, col-2, x, y, closed, heap)
add(cost+1, row+2, col-1, x, y, closed, heap)
} return ans
} // isClosed checks if the position (r, c) has been visited before.
func isClosed(closed *hashmap.Map, r, c int) bool {
set, found := closed.Get(r)
if !found {
return false
}
return set.(*hashset.Set).Contains(c)
} // close adds the position (r, c) to the closed set.
func close(closed *hashmap.Map, r, c int) {
set, found := closed.Get(r)
if !found {
set = hashset.New()
closed.Put(r, set)
}
set.(*hashset.Set).Add(c)
} // add adds the position (r, c) to the heap if it hasn't been visited before.
func add(cost, r, c, x, y int, closed *hashmap.Map, heap *binaryheap.Heap) {
if !isClosed(closed, r, c) {
heap.Push([]int{cost, distance(r, c, x, y), r, c})
}
} // distance calculates the Manhattan distance divided by 3.
// This is used as the heuristic function for estimating the cost.
func distance(r, c, x, y int) int {
return (int(math.Abs(float64(x-r))) + int(math.Abs(float64(y-c)))) / 3
} func main() {
x, y := 2, 1
result := minKnightMoves(x, y)
fmt.Println(result)
}

rust完整代码如下:

use std::cmp::Ordering;
use std::collections::{BinaryHeap, HashMap}; #[derive(Copy, Clone, Eq, PartialEq)]
struct KnightMove {
cost: i32,
distance: i32,
row: i32,
col: i32,
} impl Ord for KnightMove {
fn cmp(&self, other: &Self) -> Ordering {
(self.cost + self.distance)
.cmp(&(other.cost + other.distance))
.reverse()
}
} impl PartialOrd for KnightMove {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
} fn min_knight_moves(x: i32, y: i32) -> i32 {
let mut heap = BinaryHeap::new();
let mut closed: HashMap<i32, HashMap<i32, bool>> = HashMap::new();
heap.push(KnightMove {
cost: 0,
distance: distance(0, 0, x, y),
row: 0,
col: 0,
});
let mut ans = i32::MAX; while let Some(cur) = heap.pop() {
let cost = cur.cost;
let row = cur.row;
let col = cur.col; if is_popped(&closed, row, col) {
continue;
} if row == x && col == y {
ans = cost;
break;
} close(&mut closed, row, col);
add(cost + 1, row + 2, col + 1, x, y, &mut closed, &mut heap);
add(cost + 1, row + 1, col + 2, x, y, &mut closed, &mut heap);
add(cost + 1, row - 1, col + 2, x, y, &mut closed, &mut heap);
add(cost + 1, row - 2, col + 1, x, y, &mut closed, &mut heap);
add(cost + 1, row - 2, col - 1, x, y, &mut closed, &mut heap);
add(cost + 1, row - 1, col - 2, x, y, &mut closed, &mut heap);
add(cost + 1, row + 1, col - 2, x, y, &mut closed, &mut heap);
add(cost + 1, row + 2, col - 1, x, y, &mut closed, &mut heap);
} ans
} fn is_popped(closed: &HashMap<i32, HashMap<i32, bool>>, r: i32, c: i32) -> bool {
if let Some(cols) = closed.get(&r) {
if let Some(&popped) = cols.get(&c) {
return popped;
}
}
false
} fn close(closed: &mut HashMap<i32, HashMap<i32, bool>>, r: i32, c: i32) {
let cols = closed.entry(r).or_default();
cols.insert(c, true);
} fn add(
cost: i32,
r: i32,
c: i32,
x: i32,
y: i32,
closed: &mut HashMap<i32, HashMap<i32, bool>>,
heap: &mut BinaryHeap<KnightMove>,
) {
if !is_popped(closed, r, c) {
heap.push(KnightMove {
cost,
distance: distance(r, c, x, y),
row: r,
col: c,
});
}
} fn distance(r: i32, c: i32, x: i32, y: i32) -> i32 {
(i32::abs(x - r) + i32::abs(y - c)) / 3
} fn main() {
let x = 2;
let y = 1;
let result = min_knight_moves(x, y);
println!("Minimum knight moves: {}", result);
}

c++完整代码如下:

#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <unordered_set> using namespace std; bool isPoped(unordered_map<int, unordered_set<int>>& closed, int r, int c) {
return closed.count(r) && closed[r].count(c);
} void close(unordered_map<int, unordered_set<int>>& closed, int r, int c) {
if (!closed.count(r)) {
closed[r] = unordered_set<int>();
}
closed[r].insert(c);
} int distance(int r, int c, int x, int y); void add(int cost, int r, int c, int x, int y, unordered_map<int, unordered_set<int>>& closed,
priority_queue<vector<int>, vector<vector<int>>, greater<>>& heap) {
if (!isPoped(closed, r, c)) {
heap.push({ cost, distance(r, c, x, y), r, c });
}
} int distance(int r, int c, int x, int y) {
return (abs(x - r) + abs(y - c)) / 3;
} int minKnightMoves(int x, int y) {
priority_queue<vector<int>, vector<vector<int>>, greater<>> heap;
unordered_map<int, unordered_set<int>> closed;
heap.push({ 0, distance(0, 0, x, y), 0, 0 });
int ans = INT_MAX;
while (!heap.empty()) {
vector<int> cur = heap.top();
heap.pop();
int cost = cur[0];
int row = cur[2];
int col = cur[3];
if (isPoped(closed, row, col)) {
continue;
}
if (row == x && col == y) {
ans = cost;
break;
}
close(closed, row, col);
add(cost + 1, row + 2, col + 1, x, y, closed, heap);
add(cost + 1, row + 1, col + 2, x, y, closed, heap);
add(cost + 1, row - 1, col + 2, x, y, closed, heap);
add(cost + 1, row - 2, col + 1, x, y, closed, heap);
add(cost + 1, row - 2, col - 1, x, y, closed, heap);
add(cost + 1, row - 1, col - 2, x, y, closed, heap);
add(cost + 1, row + 1, col - 2, x, y, closed, heap);
add(cost + 1, row + 2, col - 1, x, y, closed, heap);
}
return ans;
} int main() {
int x = 2;
int y = 1;
int result = minKnightMoves(x, y);
cout << "Minimum number of knight moves: " << result << endl;
return 0;
}

2023-08-16:用go语言如何解决进击的骑士算法问题呢?的更多相关文章

  1. Oracle存储过程中不支持DML语言的解决方法(针对遇见的DROP关键字)

    ---存储过程中的原语句: ---删除表 DROP TABLE A_NEWTDDATA; --报错 经查询:存储过程不支持DML语言: 解决方法: execute immediate 'DROP TA ...

  2. http://www.cnblogs.com/alipayhutu/archive/2012/08/16/2643098.html

    http://www.cnblogs.com/alipayhutu/archive/2012/08/16/2643098.html

  3. 2021.08.16 P1260 工程规划(差分约束)

    2021.08.16 P1260 工程规划(差分约束) 重点: 1.跑最短路是为了满足更多约束条件. P1260 工程规划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 造 ...

  4. 2021.08.16 P1078 文化之旅(最短路)

    2021.08.16 P1078 文化之旅(最短路) 题意: n个地,k个信仰,每个地都有自己的信仰,信仰之间会相互排斥,同信仰之间也会相互排斥,有m条路,问从s到t的最短距离是多少? 有一位使者要游 ...

  5. 2021.08.16 P1300 城市街道交通费系统(dfs)

    2021.08.16 P1300 城市街道交通费系统(dfs) P1300 城市街道交通费系统 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 城市街道交费系统最近创立了.一 ...

  6. 2021.08.16 P1363 幻象迷宫(dfs,我感受到了出题人浓浓的恶意)

    2021.08.16 P1363 幻象迷宫(dfs,我感受到了出题人浓浓的恶意) P1363 幻象迷宫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 幻象迷宫可以认为是无限 ...

  7. 2023.1.16[模板]BSGS/exBSGS

    2023.1.16 [模板]BSGS/exBSGS 全称Boy Step Girl Step 给定一个质数 p,以及一个整数 a,一个整数 b,现在要求你计算一个最小的非负整数 l, 满足\(a^x ...

  8. 《用Python解决数据结构与算法问题》在线阅读

    源于经典 数据结构作为计算机从业人员的必备基础,Java, c 之类的语言有很多这方面的书籍,Python 相对较少, 其中比较著名的一本 problem-solving-with-algorithm ...

  9. C语言8大经典排序算法(1)

    算法一直是编程的基础,而排序算法是学习算法的开始,排序也是数据处理的重要内容.所谓排序是指将一个无序列整理成按非递减顺序排列的有序序列.排列的方法有很多,根据待排序序列的规模以及对数据的处理的要求,可 ...

  10. C语言词法分析中的贪心算法

    C语言词法分析中的贪心算法 当我们写出a---b这种语句的时候我们应该考虑C语言的编译器是如何去分析这条语句的. C语言对于解决这个问题的解决方案可以归纳为一个很简单的规则:每一个符号应该包含尽可能多 ...

随机推荐

  1. 【Azure Function App】Python Function调用Powershell脚本在Azure上执行失败的案例

    问题描述 编写Python Function,并且在Function中通过 subprocess  调用powershell.exe 执行 powershell脚本. import azure.fun ...

  2. 一次考试的T3

    啊这感觉不太可做观察性质,发现这个字符串只由ABC构成这个性质必须利用仅仅由3种字符组成意味着什么呢?这个字符串只有种可能性这个有什么用呢?只是说明暴力枚举的时间复杂度会小一些而已.不止是这些. 首先 ...

  3. 【解决】elasticsearch:Could not parse aggregation keyed as [%s]问题

    背景 在做elasticsearch集群从原来的2.x版本升级到更新版本如6.x过程中,由于需要在原来的应用中,同时连接2.x的集群以及6.x的集群来做在线动态灰度切流量,保证流量平滑切换,有问题可随 ...

  4. 洛谷P3392 涂国旗(暴力枚举)

    # 涂国旗 ## 题目描述 某国法律规定,只要一个由 $N \times M$ 个小方块组成的旗帜符合如下规则,就是合法的国旗.(毛熊:阿嚏--) - 从最上方若干行(至少一行)的格子全部是白色的: ...

  5. JVM-内部类分析

    一.内部类和外部类调用及字节码解释 外部类使用 内部类: 非静态内部类: JVM字节码 非静态内部类类 多了一个外部类对象的属性:final synthetic Field this$0:" ...

  6. 树莓派4b部署samba服务实现文件共享

    注意 samba 生命力很旺盛,软件是在不断更新的, 网上很多针对 samba 网速优化设置截止当前 实测发现有很多已经过期, 甚至有些设置会适得其反,使传输速度更低. 例如, 全网都在配置的参数,& ...

  7. SNN_文献阅读_Spiking Deep Convolutional Neural Networks for Energy-Efficient Object Recognition

    两种方法将CNN转化成为SNN: 直接训练一个类似CNN架构的SNN「虽然有类似于STDP等无监督方法,但是处于起步状态」 训练初始的CNN,将训练得到的权重直接应用于类似于CNN架构的SNN「将CN ...

  8. go基础-函数

    概述 在任何语言中函数都是极其重要的内容,业务功能都是由一个或多个函数组合完成.go语言是函数式编程语言,函数是一等公民,可以被传递.有函数类型,go语言有三种类型的函数,普通函数.匿名函数(Lamb ...

  9. 如何配置CentOS 7网络

    不久之前在配置CentOS 7网络,记录一下操作过程. CentOS 7,你可以按照以下步骤配置网络: 打开终端,输入命令查看本台服务器的IP信息. ip a 输入命令查看网关. ip r 输入命令查 ...

  10. Java程序员必备技能:Collections工具类深度解析!

    在之前的文章中,我们学习了单列集合的两大接口及其常用的实现类:在这些接口或实现类中,为我们提供了不少的实用的方法. 本篇文章我们来介绍一种java开发者为我们提供了一个工具类,让我们更好的来使用集合 ...