【秋招机试真题】华为机试0908-开源工程的最短编译时间

/*
*    题目描述:
        A公司需要在项目中引入某开源工程,需要评估该开源工程中某某块的编译时间。
    当前已知该项目中每个模块的编译时间以及其依赖的模块列表,在拥有无限数量的
    并行任务的情况下,求某个指定模块的最短编译时间。

    若模块间存在循环依赖或者依赖的模块不存在,则无法完成编译,返回-1

    输入描述:
        第一行输入为目标模块名,
        以后每行输入定义一个模块,包含模块的名字,编译时间,依赖模块列表,用逗号隔开,
        若依赖模块列表不存在,则表示可以独立编译,例如:
        module2, 10, module1
        module1, 10

        模块名只包含字母和数字且至少包含1个字符
        模块数量不超过50000个
    输出描述:
        输出最短编译时间,若无法完成编译则输出-1
*    示例1:
*        module3
*        module1, 10
*        module2, 5
*        module3, 10, module1, module2
*    输出:
*        20
*    说明:
*        module1编译需要10毫秒, module2编译需要5ms
*        module3编译依赖module1和module2,同时自身编译也需要10ms,所以总编译时间为10ms
*        所以总编译时间10+max(10, 5) = 20ms

*    示例2:
*        module2
*        module2, 10, module1
*    输出:
*        -1
*    说明:
*        module1没有定义,无法完成编译,所以输出-1
*/


说明:

        华为0908第三题,这道题和之前整理的0825第三题,基本上是类似的,输入处理不一样,输出比那道题简单一点;

        使用方法:拓扑排序|统计入度|DFS

        附上链接:【秋招机试真题】hw-任务调度系统计算任务完成所需时间


解题思路:

        1、根据输入统计每个module所依赖的module列表和每个module所需要的时间;

        2、然后根据每个module所依赖列表统计入度, 入度就是该module所依赖列表的元素个数。如果列表元素为空,说明不依赖任何module,如果没有module的入度为0,那么说明开源项目之前存在循环依赖,return -1;

        3、从target module出发,dfs该module所依赖的module,直到没有依赖的module,统计出所需要的最长时间;


代码如下:

#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
int res = 0;
void dfs(unordered_map<string, vector<string>>& depend, unordered_map<string, int>& time, string& target, int total_time) {
	if (depend[target].size() == 0) {
		res = max(res, total_time + time[target]);
		return;  // 没有依赖
	} 
	vector<string> forwards = depend[target];
	for(int i = 0; i < forwards.size(); ++ i){
		dfs(depend, time, forwards[i], total_time + time[target]);
	}
}
int solution(unordered_map<string, vector<string>>& depend, unordered_map<string, int>& time, string& target) {
	bool flag = false;
	// 统计入度, 如果没有入度为0的module,那么就是循环依赖
	for (auto iter = depend.begin(); iter != depend.end(); ++iter) {
		if (iter->second.size() == 0)  flag = true;
	}
	if (!flag) return -1;
	dfs(depend, time, target, 0);
	return res;
}
vector<string> split(string s, char c) {
	vector<string> res;
	int left = 0;
	int idx;
	string tmp;
	while (s.find(c, left) != s.npos) {
		idx = s.find(c, left);
		tmp = s.substr(left, idx - left);
		res.push_back(tmp);
		left = idx + 1;
	}
	if (left < s.size()) {
		tmp = s.substr(left, s.size() - left);
		res.push_back(tmp);
	}
	return res;
}
int main() {
	string target;
	cin >> target;
	string s;
	vector<string> tmp;
	string modu;
	unordered_map<string, vector<string>> depend;
	unordered_map<string, int> time;
	while (cin >> s) {
		tmp = split(s, ',');
		modu = tmp[0];
		time[modu] = atoi(tmp[1].c_str());
		depend[modu] = {};
		for (int i = 2; i < tmp.size(); ++i) {
			depend[modu].push_back(tmp[i]);
		}
	}
	cout << solution(depend, time, target) << endl;
}

执行结果如下:

示例1:

 示例2:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值