華為 2023年4月19日 實習 機試第一題——批次初始化次數

宇宙之母蔡依林發表於2024-04-03

某部門在開發一個程式碼分析工具,需要分析模組之間的依賴關係,用來確定模組的初始化順序,是否有迴圈依期等問題。

“批次初始化” 是指一次可以初始化一個或多個模組。

例如 模組 1 依賴模組 2, 模組 3 也依賴模組 2, 但模組 1 和 3 沒有依賴關係, 則必須先 “批次初始化” 模組 2,再 “批次初始化” 模組 1 和 3。

現給定一組模組間的依賴關係,請計算需要 “批次初始化” 的次數。

輸入

  1. 第 1 行只有一個數字.表示模組總數 NNN。
  2. 隨後的 NNN 行依次表示模組 1 到 NNN 的依賴資料。每行的第 1 個數表示依賴的模組數量(不會超過 NNN),之後的數字表示當前模組依賴的 ID 序列。該序列不會重複出現相同的數字,模組 ID 的取值定在 [1,N] 之內。
  3. 模組總數 NNN 取值範圍 1<=N<=1000
  4. 每一行裡面的數字按 1 個空格分隔。

輸出

輸出 “批次初始化次數”
若有迴圈依賴無法完成初始化,則輸出 -1。

示例一

輸入

5
3 2 3 4
1 5
1 5
1 5 0

輸出

3

說明

  • 共 5 個模組。
  • 模組 1 依賴模組 2、3、4;
  • 模組 2 依賴模組 5
  • 模組 3 依賴模組 5
  • 模組 4 依賴模組 5
  • 模組 5 沒有依賴任何模組
  • 批次初始化順序為 {5}->{2,3,4}->{1},共需 “批次初始化” 3 次

示例二

輸入

3
1 2
1 3
1 1

輸出

-1

說明

存在迴圈依賴,無法完成初始化,返回-1

解法

每次選擇出度為0的資源進行初始化,計算總共有多少躺,如果某一躺初始化的資源數為0(即找不到出度為0的資源,那麼就存在環,輸出-1返回)

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 思路:每次迭代找出出度為0的資源,刪除後再次查詢出度為0的資源
    int n;
    cin>>n;
    vector<pair<int, bool>> dg(n, {0, false});   // 出度,是否被載入
    vector<vector<bool>> map(n, vector<bool>(n, false));
    int num;
    for (int i = 0; i < n; i++) {
        cin>>dg[i].first;
        for (int j = 0; j < dg[i].first; j++) {
            cin>>num;
            map[i][num - 1] = true;
        }
    }
    int cnt = n;
    int times = 0;
    while (cnt > 0) {
        // 找出出度為0的資源
        int del = 0;
        for (int i = 0; i < n; i++) {
            if (!dg[i].second && dg[i].first == 0) {
                // 將其從其他資源的出邊刪除
                dg[i].second = true;
                for (int j = 0; j < n; j++) {
                    if (map[j][i]) {
                        map[j][i] = false;
                        dg[j].first--;
                    }
                }
                del++;
                cnt--;
            }
        }
        if (del > 0) {
            times++;
        } else if (del == 0) {
            cout<<-1<<endl;
            return 0;
        }
    }
    cout<<times<<endl;
    return 0;
}

相關文章