2023-03-11:给定一个N*M的二维矩阵,只由字符‘O‘、‘X‘、‘S‘、‘E‘组成, ‘O‘表示这个地方是可通行的平地, ‘X‘表示这个地方是不可通行的障碍, ‘S‘表示这个地方有一个士兵,全

2023-03-11:给定一个N*M的二维矩阵,只由字符’O’、‘X’、‘S’、'E’组成,
'O’表示这个地方是可通行的平地,
'X’表示这个地方是不可通行的障碍,
'S’表示这个地方有一个士兵,全图保证只有一个士兵,
'E’表示这个地方有一个敌人,全图保证只有一个敌人,
士兵可以在上、下、左、右四个方向上移动,
走到相邻的可通行的平地上,走一步耗费a个时间单位,
士兵从初始地点行动时,不管去哪个方向,都不用耗费转向的代价,
但是士兵在行动途中,如果需要转向,需要额外再付出b个时间单位。
返回士兵找到敌人的最少时间。
如果因为障碍怎么都找不到敌人,返回-1,
1 <= N,M <= 1000,
1 <= a,b <= 100000,
只会有一个士兵、一个敌人。
来自华为。

答案2023-03-11:

Dijkstra算法+优先级队列。

代码根据山寨版chatgpt稍做修改写的。这不得不承认chatgpt很强大,这还是山寨版的,感觉比我自己写得还要好。

以下代码是生成的rust代码,稍微做了修改。如下:

use rand::Rng;
use std::cmp::Reverse;
use std::collections::BinaryHeap;
fn random_map(n: usize, m: usize) -> Vec<Vec<char>> {let mut map = vec![vec!['O'; m]; n];for i in 0..n {for j in 0..m {if rand::thread_rng().gen_range(0, 2) == 0 {map[i][j] = 'X';}}}let si = rand::thread_rng().gen_range(0, n);let sj = rand::thread_rng().gen_range(0, m);map[si][sj] = 'S';let (mut ei, mut ej) = (si, sj);while ei == si && ej == sj {ei = rand::thread_rng().gen_range(0, n);ej = rand::thread_rng().gen_range(0, m);}map[ei][ej] = 'E';map
}fn main() {let n = 3;let m = 4;let v = 10;println!("功能测试开始");for _ in 0..2000 {let map = random_map(n, m);let a = rand::thread_rng().gen_range(1, v + 1);let b = rand::thread_rng().gen_range(1, v + 1);let ans1 = min_cost1(&map, a, b);let ans2 = min_cost2(&map, a, b);if ans1 != ans2 {println!("出错了");println!("{}", ans1);println!("{}", ans2);return;}}println!("功能测试结束");println!("性能测试开始");let n = 1000;let m = 1000;let v = 100000;let a = rand::thread_rng().gen_range(1, v + 1);let b = rand::thread_rng().gen_range(1, v + 1);let map = random_map(n, m);println!("数据规模 : {} * {}", n, m);println!("通行代价 : {}", a);println!("转向代价 : {}", b);let start = std::time::Instant::now();min_cost2(&map, a, b);let end = std::time::Instant::now();println!("运行时间 : {}毫秒", (end - start).as_millis());println!("功能测试结束");
}fn min_cost1(map: &[Vec<char>], a: i32, b: i32) -> i32 {let n = map.len();let m = map[0].len();let mut start_x = 0;let mut start_y = 0;for i in 0..n {for j in 0..m {if map[i][j] == 'S' {start_x = i;start_y = j;}}}let mut visited = vec![vec![vec![false; 4]; m]; n];let p1 = f(&map, start_x, start_y, 0, a, b, &mut visited);let p2 = f(&map, start_x, start_y, 1, a, b, &mut visited);let p3 = f(&map, start_x, start_y, 2, a, b, &mut visited);let p4 = f(&map, start_x, start_y, 3, a, b, &mut visited);let ans = p1.min(p2).min(p3).min(p4);if ans == i32::MAX {-1} else {ans - a}
}fn f(map: &[Vec<char>],si: usize,sj: usize,d: usize,a: i32,b: i32,visited: &mut Vec<Vec<Vec<bool>>>,
) -> i32 {let n = map.len();let m = map[0].len();if si >= n || sj >= m || map[si][sj] == 'X' || visited[si][sj][d] {return i32::MAX;}if map[si][sj] == 'E' {return a;}visited[si][sj][d] = true;let p0 = f(&map, si.checked_sub(1).unwrap_or(0), sj, 0, a, b, visited);let p1 = f(&map, si + 1, sj, 1, a, b, visited);let p2 = f(&map, si, sj.checked_sub(1).unwrap_or(0), 2, a, b, visited);let p3 = f(&map, si, sj + 1, 3, a, b, visited);let p0 = if d != 0 && p0 != i32::MAX { p0 + b } else { p0 };let p1 = if d != 1 && p1 != i32::MAX { p1 + b } else { p1 };let p2 = if d != 2 && p2 != i32::MAX { p2 + b } else { p2 };let p3 = if d != 3 && p3 != i32::MAX { p3 + b } else { p3 };let ans = p0.min(p1).min(p2).min(p3);visited[si][sj][d] = false;if ans == i32::MAX {ans} else {ans + a}
}fn min_cost2(map: &[Vec<char>], a: i32, b: i32) -> i32 {let n = map.len();let m = map[0].len();let mut start_x = 0;let mut start_y = 0;for i in 0..n {for j in 0..m {if map[i][j] == 'S' {start_x = i;start_y = j;}}}let mut heap = BinaryHeap::new();heap.push((Reverse(0), start_x, start_y, 0));heap.push((Reverse(0), start_x, start_y, 1));heap.push((Reverse(0), start_x, start_y, 2));heap.push((Reverse(0), start_x, start_y, 3));// (i,j,朝向)let mut visited = vec![vec![vec![false; 4]; m]; n];let mut ans = -1;while let Some((Reverse(cost), x, y, direction)) = heap.pop() {if visited[x][y][direction] {continue;}if map[x][y] == 'E' {ans = cost;break;}visited[x][y][direction] = true;add(x as i32 - 1,y as i32,0,direction,cost,a,b,map,&mut visited,&mut heap,);add(x as i32 + 1,y as i32,1,direction,cost,a,b,map,&mut visited,&mut heap,);add(x as i32,y as i32 - 1,2,direction,cost,a,b,map,&mut visited,&mut heap,);add(x as i32,y as i32 + 1,3,direction,cost,a,b,map,&mut visited,&mut heap,);}ans
}// 从(x,y, pre_d) -> (i,j,d)
// 走格子的代价a
// 转向的代价是b
// pre_c + a
fn add(i: i32,j: i32,direction: usize,pre_direction: usize,pre_cost: i32,a: i32,b: i32,map: &[Vec<char>],visited: &mut Vec<Vec<Vec<bool>>>,heap: &mut BinaryHeap<(Reverse<i32>, usize, usize, usize)>,
) {let n = map.len() as i32;let m = map[0].len() as i32;if i < 0|| i >= n|| j < 0|| j >= m|| map[i as usize][j as usize] == 'X'|| visited[i as usize][j as usize][direction]{return;}let mut cost = pre_cost + a;if direction != pre_direction {cost += b;}heap.push((Reverse(cost), i as usize, j as usize, direction));
}

在这里插入图片描述
以下代码是生成的golang代码,稍微做了修改。如下:

package mainimport ("container/heap""fmt""math/rand""time"
)func minCost1(mapData [][]byte, a int, b int) int {// 获取地图大小和起点位置n, m := len(mapData), len(mapData[0])startX, startY := 0, 0for i := 0; i < n; i++ {for j := 0; j < m; j++ {if mapData[i][j] == 'S' {startX, startY = i, jbreak}}}// 初始化 visited 数组visited := make([][][]bool, n)for i := range visited {visited[i] = make([][]bool, m)for j := range visited[i] {visited[i][j] = make([]bool, 4)}}// 计算从四个方向到达终点的最短距离p1 := f(mapData, startX, startY, 0, a, b, visited)p2 := f(mapData, startX, startY, 1, a, b, visited)p3 := f(mapData, startX, startY, 2, a, b, visited)p4 := f(mapData, startX, startY, 3, a, b, visited)// 返回四个方向中最小的距离ans := min(p1, min(p2, min(p3, p4)))if ans == 1<<31-1 {return -1} else {return ans - a}
}func f(mapData [][]byte, si int, sj int, d int, a int, b int, visited [][][]bool) int {// 如果出现越界、墙壁或者已经访问过的情况,返回一个大整数表示无法到达该位置if si < 0 || si == len(mapData) || sj < 0 || sj == len(mapData[0]) || mapData[si][sj] == 'X' || visited[si][sj][d] {return 1<<31 - 1}// 如果到达终点,返回 a 表示到达终点所需的代价if mapData[si][sj] == 'E' {return a}// 标记该位置已经被访问过visited[si][sj][d] = true// 计算从四个方向到达下一个位置所需的代价(如果可以到达的话)var p [4]intp[0] = f(mapData, si-1, sj, 0, a, b, visited)p[1] = f(mapData, si+1, sj, 1, a, b, visited)p[2] = f(mapData, si, sj-1, 2, a, b, visited)p[3] = f(mapData, si, sj+1, 3, a, b, visited)if d != 0 && p[0] != 1<<31-1 {p[0] += b}if d != 1 && p[1] != 1<<31-1 {p[1] += b}if d != 2 && p[2] != 1<<31-1 {p[2] += b}if d != 3 && p[3] != 1<<31-1 {p[3] += b}// 返回四个方向中最小的代价,并且取消对该位置的访问标记ans := min(p[0], min(p[1], min(p[2], p[3])))visited[si][sj][d] = falseif ans == 1<<31-1 {return ans} else {return ans + a}
}func min(a int, b int) int {if a < b {return a} else {return b}
}func minCost2(mapData [][]byte, a int, b int) int {// 获取地图大小和起点位置n, m := len(mapData), len(mapData[0])startX, startY := 0, 0for i := 0; i < n; i++ {for j := 0; j < m; j++ {if mapData[i][j] == 'S' {startX, startY = i, jbreak}}}// 初始化优先队列和 visited 数组h := &minHeap{}heap.Init(h)heap.Push(h, node{startX, startY, 0, 0})heap.Push(h, node{startX, startY, 1, 0})heap.Push(h, node{startX, startY, 2, 0})heap.Push(h, node{startX, startY, 3, 0})visited := make([][][]bool, n)for i := range visited {visited[i] = make([][]bool, m)for j := range visited[i] {visited[i][j] = make([]bool, 4)}}// 运行 Dijkstra 算法并返回答案ans := -1for h.Len() > 0 {cur := heap.Pop(h).(node)if visited[cur.x][cur.y][cur.dir] {continue}if mapData[cur.x][cur.y] == 'E' {ans = cur.costbreak}visited[cur.x][cur.y][cur.dir] = trueadd(cur.x-1, cur.y, 0, cur.dir, cur.cost, a, b, mapData, visited, h)add(cur.x+1, cur.y, 1, cur.dir, cur.cost, a, b, mapData, visited, h)add(cur.x, cur.y-1, 2, cur.dir, cur.cost, a, b, mapData, visited, h)add(cur.x, cur.y+1, 3, cur.dir, cur.cost, a, b, mapData, visited, h)}return ans
}type node struct {x, y, dir, cost int
}type minHeap []nodefunc (h minHeap) Len() int { return len(h) }func (h minHeap) Less(i, j int) bool { return h[i].cost < h[j].cost }func (h minHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }func (h *minHeap) Push(x interface{}) { *h = append(*h, x.(node)) }func (h *minHeap) Pop() interface{} {old := *hn := len(old)x := old[n-1]*h = old[:n-1]return x
}func add(i, j, d, preD, preC, a, b int, mapData [][]byte, visited [][][]bool, h *minHeap) {if i < 0 || i == len(mapData) || j < 0 || j == len(mapData[0]) || mapData[i][j] == 'X' || visited[i][j][d] {return}cost := preC + aif d != preD {cost += b}heap.Push(h, node{i, j, d, cost})
}func randomMap(n, m int) [][]byte {mapData := make([][]byte, n)for i := range mapData {mapData[i] = make([]byte, m)for j := range mapData[i] {if rand.Float32() < 0.5 {mapData[i][j] = 'O'} else {mapData[i][j] = 'X'}}}si := rand.Intn(n)sj := rand.Intn(m)mapData[si][sj] = 'S'var ei, ej intfor {ei = rand.Intn(n)ej = rand.Intn(m)if ei != si || ej != sj {break}}mapData[ei][ej] = 'E'return mapData
}func main() {n, m := 3, 4v := 10fmt.Println("功能测试开始")for i := 0; i < 2000; i++ {mapData := randomMap(n, m)a := rand.Intn(v) + 1b := rand.Intn(v) + 1ans1 := minCost1(mapData, a, b)ans2 := minCost2(mapData, a, b)if ans1 != ans2 {fmt.Println("出错了")fmt.Println(ans1)fmt.Println(ans2)}}fmt.Println("功能测试结束")fmt.Println("性能测试开始")n = 1000m = 1000v = 100000a := rand.Intn(v) + 1b := rand.Intn(v) + 1mapData := randomMap(n, m)fmt.Println("数据规模 : ", n, " * ", m)fmt.Println("通行代价 : ", a)fmt.Println("转向代价 : ", b)start := time.Now()minCost2(mapData, a, b)end := time.Now()fmt.Println("运行时间 : ", end.Sub(start))fmt.Println("功能测试结束")
}

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/12773.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我的ChatGPT学习笔记004

大家好啊&#xff0c;我是了不起&#xff01; 前一段时间ChatGPT突然火爆&#xff0c;大佬们纷纷下场。我也跟着努力学习&#xff0c;做了一些笔记。 下面将陆续放出笔记&#xff0c;共享给小伙伴们&#xff01;这是放出的第二篇&#xff0c;和小伙伴们与时俱进哈~~ 笔记四&…

这几天chatGPT为我赚了多少钱

大家好&#xff0c;我是北妈。 一、 这些天chaGPT 有多火你们也看到了。都不用我发文教育你们&#xff0c;给你们传播了&#xff0c;各大媒体&#xff0c;朋友圈都是它的消息了吧。 至于利用它为北妈我赚了多少钱&#xff0c;其实不少了&#xff0c;通过各种渠道和方法。以后可…

[转] ChatGPT热引发年薪千万高管辞职潮

一场技术天花板的创业。 文&#xff5c;《中国企业家》记者 闫俊文 编辑&#xff5c;李薇 图片来源&#xff5c;视觉中国 ChatGPT以及背后的GPT大模型&#xff0c;正在引发一场创业地震。 李开复、王慧文、王小川&#xff0c;不仅这些“退休”的互联网老兵加入了&#xff0c;在…

完蛋!ChatGPT 完全取代了我的 Java 编程工作!

因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享 点击关注#互联网架构师公众号&#xff0c;领取架构师全套资料 都在这里 0、2T架构师学习资料干货分 上一篇&#xff1a;ChatGPT研究框架&#xff08;80页PPT&#xff0c;附下载&#xff09;…

ChatGPT思考:探索智能的极限

作者&#xff1a;符尧 yao.fued.ac.uk University of Edinburgh & Allen Institute for AI 海外独角兽和拾象一直抱着开源研究&#xff0c;开放分享的心态&#xff0c;本文是拾象 Fellow 符尧关于 ChatGPT 的新思考。符尧曾写过一篇非常精彩的拆解GPT3起源的文章&#xf…

ChatGPT 给我们 带来的哲学思考

ChatGPT 给我们 带来的哲学思考 ChatGPT 是一种基于 GPT-3 模型的聊天机器人&#xff0c;它可以与人类进行自然、流畅、有趣的对话。ChatGPT 的出现&#xff0c;不仅是人工智能技术的一次重大突破&#xff0c;也是对人类社会和文化的一次挑战。ChatGPT 给我们带来了一些哲学上…

Netflix 总用户达到 2.325 亿;马斯克打脸创建 X.AI 公司;印度首开苹果门店;谷歌老板对 AI 很担心?特斯拉营收增加,但净利润下降…《经济学人 | 第 17 期 | 速读版》

快速阅读版&#xff0c;完整英文解析版见&#xff1a; https://blog.csdn.net/YopenLang/article/details/130375444 中国第一季度经济增长出乎意料 中国第一季度经济同比增长 4.5%&#xff0c;超出了大多数经济学家的预期。 China’s economy grew by 4.5% in the first quart…

大火的 ChatGPT,让中国式教育面临巨大挑战?

大火的 ChatGPT&#xff0c;让中国式教育面临巨大挑战&#xff0c;ChatGPT是目前最先进的人工智能聊天机器人。它有多牛呢&#xff1f; 特斯拉的老板马斯克赞美它&#xff1a;“好得吓人。 苹果的老板库克赞美它&#xff1a;“不可思议。 微软的老板比尔盖茨赞美它&…

chatgpt赋能python:Python如何进行分步运行

Python如何进行分步运行 Python是一种强大的编程语言&#xff0c;可以用于开发各种应用程序和Web应用程序。在Python中&#xff0c;您可以使用一些简单的技术来分步运行程序&#xff0c;这将使您更容易调试程序并更好地理解程序的工作原理。在本文中&#xff0c;我们将介绍如何…

chatgpt赋能python:利用Python编写模拟器:一种循序渐进的方法

利用Python编写模拟器&#xff1a;一种循序渐进的方法 模拟器是一种用于模拟计算机硬件或软件的程序。它模拟了真实设备的功能&#xff0c;可以帮助开发人员进行测试和调试&#xff0c;以及提供一种环境来设计和验证新的算法和协议。Python是一种广泛使用的编程语言&#xff0…

chatgpt赋能python:Python如何打断点——提高调试效率

Python如何打断点——提高调试效率 Python是一种易于学习、易于编写和易于调试的高级编程语言。调试是编程过程中必不可少的步骤&#xff0c;打断点是其中一个最常用的工具。打断点可以让程序在指定行停止执行&#xff0c;以便程序员可以检查代码和变量值&#xff0c;以及测试…

chatgpt赋能python:Python快捷键设置介绍

Python快捷键设置介绍 Python是一种高级编程语言&#xff0c;也是众多程序员和开发者广泛采用的语言之一。虽然Python作为一种易学易用的语言&#xff0c;但学习Python仍然需要一定的时间和耐心。其中Python快捷键设置可以让编程变得更加快速和高效。 Python快捷键设置能够更…

chatgpt赋能python:Python调试技巧:如何使用断点运行程序

Python调试技巧&#xff1a;如何使用断点运行程序 在Python编程中&#xff0c;程序出现错误或需要调试时&#xff0c;我们需要一些工具来帮助我们定位问题和修复代码。其中之一就是使用断点来运行程序。接下来我们将讨论如何在Python中使用断点进行程序调试的相关技巧。 什么…

chatgpt赋能Python-python_chariot

Python Chariot&#xff1a;一款强大的Python IDE Python Chariot是一款强大的Python IDE&#xff0c;它的特点是简单易用&#xff0c;功能齐全。该IDE适用于各种Python编程任务&#xff0c;无论是编写小型脚本还是大型项目。在本文中&#xff0c;我们将深入介绍Python Chario…

ChatGPT、Java 8 文档、MySQL都说 JDBC 没必要 `Class.forName()`,结果报错了……

文章目录 回顾 Tomcat 部署 WAR 应用报错找不到数据库驱动的问题ChatGPT、Javadoc 和 MySQL 驱动都说没必要 Class.forName()实验创建一个最小复现问题的 Demo不调用 Class.forName("com.mysql.cj.jdbc.Driver")调用 Class.forName("com.mysql.cj.jdbc.Driver&q…

chatgpt赋能Python-pythonctrl快捷键

PythonCtrl快捷键使用指南 作为一名有10年Python编程经验的工程师&#xff0c;我深知PythonCtrl快捷键的重要性。PythonCtrl作为一个Python的开源编辑器&#xff0c;在每一个版本中都加入了更多的功能和快捷键&#xff0c;使得Python编程更加高效和易用。在本篇文章中&#xf…

chatgpt赋能python:Python如何查错

Python如何查错 Python是一种高级编程语言&#xff0c;由于其良好的可读性和易于学习的特性&#xff0c;成为了众多开发人员的首选。但是&#xff0c;编写Python程序时难免会遇到错误&#xff0c;为了节省时间和提高效率&#xff0c;本文将介绍如何使用Python查错。 1. 抛出异…

chatgpt赋能python:Python程序改错

Python程序改错 Python是一种面向对象的动态编程语言&#xff0c;拥有近20年的发展历程&#xff0c;并逐渐成为全球范围内最受欢迎的编程语言之一。与其它编程语言相同&#xff0c;Python程序也会出现错误&#xff0c;有时候这些错误很难找到和解决。为了帮助有需要的读者&…

chatgpt赋能python:Python如何使用断点进行调试

Python 如何使用断点进行调试 Python是一种易于学习和读写的编程语言&#xff0c;但是在编写代码的过程中&#xff0c;难免会遇到某些代码无法正常运行或者出现错误。这时候&#xff0c;我们就需要使用调试工具来找出问题所在&#xff0c;而打断点是一种方便的调试方法。 什么…

chatgpt赋能python:Python断点调试指南:让调试更高效

Python断点调试指南&#xff1a;让调试更高效 在Python编程中&#xff0c;调试是一个必不可少的环节。当我们面临代码出现错误或程序不按预期运行时&#xff0c;如何快速找到问题&#xff0c;解决它们呢&#xff1f;这时候断点调试就发挥了重要的作用。本篇文章主要介绍Python…