2023-10-18:用go语言,给定一个数组arr,长度为n,表示有0~n-1号设备, arr[i]表示i号设备的型号,型号的种类从0~k-1,一共k种型号, 给定一个k*k的矩阵map,来表示型号
2023-10-18:用go語言,給定一個(gè)數(shù)組arr,長度為n,表示有0~n-1號(hào)設(shè)備,
arr[i]表示i號(hào)設(shè)備的型號(hào),型號(hào)的種類從0~k-1,一共k種型號(hào),
給定一個(gè)k*k的矩陣map,來表示型號(hào)之間的兼容情況,
map[a][b] == 1,表示a型號(hào)兼容b型號(hào),
map[a][b] == 0,表示a型號(hào)不兼容b型號(hào),
兼容關(guān)系是有向圖,也就是a型號(hào)兼容b型號(hào),不代表b型號(hào)同時(shí)兼容a型號(hào),
如果i設(shè)備的型號(hào)兼容j設(shè)備的型號(hào),那么可以從i設(shè)備修建一條去往j設(shè)備的線路,
修建線路的代價(jià)是i設(shè)備到j(luò)設(shè)備的距離:|i-j|,
你的目標(biāo)是從0號(hào)設(shè)備到達(dá)n-1號(hào)設(shè)備,并不一定每個(gè)設(shè)備都聯(lián)通,只需要到達(dá)即可。
返回最小的修建代價(jià),如果就是無法到達(dá)返回-1。
1 <= n <= 1000,
1 <= k <= 50。
來自招商銀行。
來自左程云。
答案2023-10-18:
大體步驟:
1.創(chuàng)建一個(gè)二維切片 own,長度為 k,用于記錄每個(gè)型號(hào)的設(shè)備編號(hào)。
2.創(chuàng)建一個(gè)二維切片 nexts,長度為 k,用于記錄每個(gè)型號(hào)兼容的下一個(gè)型號(hào)。
3.遍歷數(shù)組 arr,將每個(gè)設(shè)備的編號(hào)添加到對(duì)應(yīng)型號(hào)的 own 中。
4.遍歷兼容矩陣 m,將每個(gè)型號(hào)兼容的下一個(gè)型號(hào)添加到對(duì)應(yīng)型號(hào)的 nexts 中。
5.創(chuàng)建一個(gè)二叉堆 heap,并定義排序函數(shù),按照修建代價(jià)升序排列。
6.將起始設(shè)備 (0, 0) 添加到堆中,表示從 0 號(hào)設(shè)備開始,修建代價(jià)為 0。
7.創(chuàng)建一個(gè)長度為 n 的布爾型切片 visited,用于標(biāo)記設(shè)備是否被訪問過。
8.當(dāng)堆不為空時(shí),進(jìn)行以下操作:
彈出堆頂元素
t,表示當(dāng)前位置和當(dāng)前的修建代價(jià)。獲取當(dāng)前位置
cur的設(shè)備編號(hào)和修建代價(jià)。如果當(dāng)前位置為目標(biāo)位置
n-1,則返回當(dāng)前的修建代價(jià)。將當(dāng)前位置標(biāo)記為已訪問。
9.獲取當(dāng)前設(shè)備的型號(hào) model。
10.遍歷下一個(gè)兼容的型號(hào) nextModel,以及擁有下一個(gè)型號(hào) nextModel 的設(shè)備位置 nextPosition:
- 如果設(shè)備位置未被訪問過,則將 `(nextPosition, cost + abs(nextPosition, position))` 添加到堆中。
11.如果無法到達(dá)目標(biāo)位置,返回 -1。
12.在 main 函數(shù)中調(diào)用 minCost 函數(shù),并輸出結(jié)果。
總的時(shí)間復(fù)雜度為 $O(nk^2logn)$,其中 n 是設(shè)備數(shù)量,k 是型號(hào)數(shù)量。遍歷擁有型號(hào)的設(shè)備位置的過程復(fù)雜度為 O(n),堆操作的復(fù)雜度為 O(logn),遍歷所有可能的型號(hào)和設(shè)備位置的復(fù)雜度為 $O(k^2$),所以總的時(shí)間復(fù)雜度為 $O(nk^2logn)$。
總的額外空間復(fù)雜度為 O(n),其中 n 是設(shè)備數(shù)量。需要額外的空間來存儲(chǔ) own、nexts、visited 和堆 heap,它們的空間復(fù)雜度都為 O(n)。
go完整代碼如下:
package main
import (
"fmt"
"github.com/emirpasic/gods/trees/binaryheap"
)
func minCost(arr []int, m [][]int, n int, k int) int {
// 0 : {4,7,13,26}
// 1 : {5,45,3,17}
own := make([][]int, k)
nexts := make([][]int, k)
for i := 0; i < k; i++ {
own[i] = []int{}
nexts[i] = []int{}
}
for i := 0; i < n; i++ {
own[arr[i]] = append(own[arr[i]], i)
}
for i := 0; i < k; i++ {
for j := 0; j < k; j++ {
if m[i][j] == 1 {
nexts[i] = append(nexts[i], j)
}
}
}
heap := binaryheap.NewWith(func(a, b interface{}) int {
return a.([]int)[1] - b.([]int)[1]
})
heap.Push([]int{0, 0})
visited := make([]bool, n)
for heap.Size() > 0 {
t, _ := heap.Pop()
cur := t.([]int)
position := cur[0]
cost := cur[1]
if !visited[position] {
visited[position] = true
if position == n-1 {
return cost
}
model := arr[position]
for _, nextModel := range nexts[model] {
for _, nextPosition := range own[nextModel] {
if !visited[nextPosition] {
heap.Push([]int{nextPosition, cost + abs(nextPosition, position)})
}
}
}
}
}
return -1
}
func abs(a, b int) int {
if a-b < 0 {
return b - a
}
return a - b
}
func main() {
arr := []int{0, 1, 2, 3}
m := [][]int{{0, 1, 0, 1, 0}, {1, 0, 1, 1, 0}, {2, 1, 1, 1, 1}, {3, 0, 0, 0, 0}}
n := 4
k := 4
result := minCost(arr, m, n, k)
fmt.Println(result)
}

rust完整代碼如下:
use std::cmp::Reverse;
use std::collections::BinaryHeap;
fn min_cost(arr: &[i32], map: &[Vec<i32>], n: usize, k: usize) -> i32 {
let mut own: Vec<Vec<i32>> = vec![Vec::new(); k];
let mut nexts: Vec<Vec<i32>> = vec![Vec::new(); k];
for (i, &value) in arr.iter().enumerate() {
own[value as usize].push(i as i32);
}
for (i, row) in map.iter().enumerate() {
for (j, &value) in row.iter().enumerate() {
if value == 1 {
nexts[i as usize].push(j as i32);
}
}
}
let mut heap: BinaryHeap<(i32, i32)> = BinaryHeap::new();
heap.push((0, 0));
let mut visited: Vec<bool> = vec![false; n];
while let Some((position, cost)) = heap.pop() {
let position = position as usize;
let cost = cost;
if !visited[position] {
visited[position] = true;
if position == n - 1 {
return cost;
}
let model = arr[position] as usize;
for &next_model in &nexts[model] {
for &next_position in &own[next_model as usize] {
if !visited[next_position as usize] {
heap.push((
next_position,
cost + (next_position - position as i32).abs(),
));
}
}
}
}
}
-1
}
fn main() {
let arr = [0, 1, 2, 3];
let m = [
vec![0, 1, 0, 1, 0],
vec![1, 0, 1, 1, 0],
vec![2, 1, 1, 1, 1],
vec![3, 0, 0, 0, 0],
];
let n = 4;
let k = 4;
let result = min_cost(&arr, &m, n, k);
println!("Minimum Cost: {}", result);
}

c++完整代碼如下:
#include <iostream>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
int minCost(vector<int>& arr, vector<vector<int>>& map, int n, int k) {
vector<vector<int>> own(k);
vector<vector<int>> nexts(k);
for (int i = 0; i < n; i++) {
own[arr[i]].push_back(i);
}
for (int i = 0; i < k; i++) {
for (int j = 0; j < k; j++) {
if (map[i][j] == 1) {
nexts[i].push_back(j);
}
}
}
priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> heap;
heap.push({ 0, 0 });
vector<bool> visited(n, false);
while (!heap.empty()) {
vector<int> cur = heap.top();
heap.pop();
int position = cur[0];
int cost = cur[1];
if (!visited[position]) {
visited[position] = true;
if (position == n - 1) {
return cost;
}
int model = arr[position];
for (int nextModel : nexts[model]) {
for (int nextPosition : own[nextModel]) {
if (!visited[nextPosition]) {
heap.push({ nextPosition, cost + abs(nextPosition - position) });
}
}
}
}
}
return -1;
}
int main() {
vector<int> arr = { 0, 1, 2, 3 };
vector<vector<int>> m = { {0, 1, 0, 1, 0}, {1, 0, 1, 1, 0}, {2, 1, 1, 1, 1}, {3, 0, 0, 0, 0} };
int n = 4;
int k = 4;
int result = minCost(arr, m, n, k);
cout << result << endl;
return 0;
}

總結(jié)
以上是生活随笔為你收集整理的2023-10-18:用go语言,给定一个数组arr,长度为n,表示有0~n-1号设备, arr[i]表示i号设备的型号,型号的种类从0~k-1,一共k种型号, 给定一个k*k的矩阵map,来表示型号的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信奥赛题1001:Hello,World
- 下一篇: Java-旋转字符串