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-旋转字符串
