- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
java解法
我们有多个服务之间的依赖关系和一些故障的服务。每个服务可能依赖于其他服务,并且如果一个服务故障了,所有依赖它的服务也会受到影响,不能正常工作。
任务是找出哪些服务在给定的故障服务集和依赖关系下仍然能够正常工作。
关键概念:
依赖关系:每个服务可能依赖于其他服务。我们可以将这些依赖关系看作一个有向图,其中每个服务为一个节点,依赖关系为有向边。
故障传播:故障是从已故障的服务开始的,所有依赖于这些服务的服务都会受影响。
拓扑排序:服务之间有依赖顺序,输出时要按照服务的顺序排列。
步骤:
解析输入:解析依赖关系和故障服务。
构建依赖图:根据依赖关系构建一个图,记录每个服务依赖的服务。
故障传播:从故障服务开始,使用深度优先搜索(DFS)或者栈来传播故障,标记所有受影响的服务。
筛选正常工作服务:所有没有被故障影响的服务才是正常工作的服务。
按顺序输出:输出正常工作的服务,并根据它们的顺序排序
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String relInput = sc.nextLine();
List<String> relPairs = split(relInput, ',');
List<Pair<String, String>> rels = new ArrayList<>();
for (String pStr : relPairs) {
List<String> p = split(pStr, '-');
rels.add(new Pair<>(p.get(0), p.get(1)));
}
String failInput = sc.nextLine();
List<String> fails = split(failInput, ',');
System.out.println(getActive(rels, fails));
}
public static List<String> split(String s, char d) {
return Arrays.asList(s.split(String.valueOf(d)));
}
public static String getActive(List<Pair<String, String>> rels, List<String> fails) {
Map<String, Set<String>> depMap = new HashMap<>();
Set<String> failSet = new HashSet<>(fails);
Map<String, Integer> orderMap = new HashMap<>();
int idx = 0;
for (Pair<String, String> rel : rels) {
String dep = rel.getKey();
String prov = rel.getValue();
depMap.computeIfAbsent(prov, k -> new HashSet<>()).add(dep);
orderMap.putIfAbsent(dep, idx++);
orderMap.putIfAbsent(prov, idx++);
}
for (String fail : fails) {
Stack<String> stk = new Stack<>();
stk.push(fail);
while (!stk.isEmpty()) {
String svc = stk.pop();
if (depMap.containsKey(svc)) {
for (String dep : depMap.get(svc)) {
if (!failSet.contains(dep)) {
failSet.add(dep);
stk.push(dep);
}
}
depMap.remove(svc);
}
}
}
List<String> operList = new ArrayList<>();
for (Map.Entry<String, Integer> entry : orderMap.entrySet()) {
if (!failSet.contains(entry.getKey())) {
operList.add(entry.getKey());
}
}
if (operList.isEmpty()) {
return ",";
}
operList.sort(Comparator.comparingInt(orderMap::get));
return String.join(",", operList);
}
public static class Pair<K, V> {
private final K key;
private final V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
C++解法
- 解题思路
- 该问题的核心是模拟一组服务的依赖关系,并根据故障服务的传播,找出最终哪些服务是可用的。故障从故障服务开始传播,影响到所有依赖于该服务的其他服务。最后,我们需要输出剩余可用的服务,并按照它们的出现顺序排序。
步骤概述:
输入解析:
输入包含两部分:服务的依赖关系和故障服务。
服务依赖关系是“服务1-服务2”的形式,表示服务2依赖服务1。
故障服务是一个以逗号分隔的字符串,表示这些服务已经失败。
构建依赖图:
使用map dependencyMap来存储依赖关系图,其中dependencyMap[provider]表示提供服务的服务所依赖的服务集合。
使用map appearanceOrder来为每个服务分配一个顺序编号,以便我们在最后根据顺序输出。
故障传播:
对每个故障服务,通过栈模拟深度优先搜索(DFS)来标记所有因故障服务而故障的服务。
如果服务依赖于故障服务,它也会故障。继续传播,直到所有受影响的服务都被标记为故障。
筛选正常服务:
遍历所有服务,选出那些没有被故障影响的服务。
输出:
对所有剩余的正常服务按照它们的顺序进行排序,然后按顺序输出
#include
#include
#include
#include
#include
#include
#include
using namespace std;
vector<string> split(const string& s, char delimiter) {
vector<string> tokens;
string token;
istringstream tokenStream(s);
while (getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
string determineActiveServices(const vector<pair<string, string>>& relations, const vector<string>& failures) {
map<string, set<string>> dependencyMap;
set<string> failureSet(failures.begin(), failures.end());
map<string, int> appearanceOrder;
int index = 0;
for (const auto& relation : relations) {
const string& dependent = relation.first;
const string& provider = relation.second;
dependencyMap[provider].insert(dependent);
if (appearanceOrder.find(dependent) == appearanceOrder.end()) {
appearanceOrder[dependent] = index++;
}
if (appearanceOrder.find(provider) == appearanceOrder.end()) {
appearanceOrder[provider] = index++;
}
}
for (const auto& failure : failures) {
stack<string> stack;
stack.push(failure);
while (!stack.empty()) {
string service = stack.top();
stack.pop();
if (dependencyMap.find(service) != dependencyMap.end()) {
for (const auto& dependent : dependencyMap[service]) {
if (failureSet.find(dependent) == failureSet.end()) {
failureSet.insert(dependent);
stack.push(dependent);
}
}
dependencyMap.erase(service);
}
}
}
vector<string> operationalList;
for (const auto& entry : appearanceOrder) {
if (failureSet.find(entry.first) == failureSet.end()) {
operationalList.push_back(entry.first);
}
}
if (operationalList.empty()) {
return ",";
}
sort(operationalList.begin(), operationalList.end(), [&](const string& a, const string& b) {
return appearanceOrder[a] < appearanceOrder[b];
});
string result = operationalList[0];
for (size_t i = 1; i < operationalList.size(); ++i) {
result += "," + operationalList[i];
}
return result;
}
int main() {
string relationsInput;
getline(cin, relationsInput);
vector<string> relationsPairs = split(relationsInput, ',');
vector<pair<string, string>> relations;
for (const auto& pairStr : relationsPairs) {
vector<string> pair = split(pairStr, '-');
relations.emplace_back(pair[0], pair[1]);
}
string failuresInput;
getline(cin, failuresInput);
vector<string> failures = split(failuresInput, ',');
cout << determineActiveServices(relations, failures) << endl;
return 0;
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
C解法
更新中
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
JS解法
主要步骤:
解析输入数据:首先解析依赖关系和故障服务的输入。
构建服务依赖图:根据输入的依赖关系,构建一个图,其中每个服务对应着它依赖的服务。
故障传播:对于每个故障服务,递归地标记所有受影响的服务。
筛选可用服务:在传播完所有故障后,筛选出那些未被标记为故障的服务,并按它们出现的顺序输出。
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const ln = [];
rl.on("line", (line) => {
ln.push(line);
if (ln.length === 2) {
const rel = ln[0].split(",").map((p) => p.split("-"));
const brk = ln[1].split(",");
console.log(getNorm(rel, brk));
ln.length = 0;
}
});
function getNorm(rel, brk) {
const nxt = {};
const fst = {};
let idx = 0;
for (let [c, f] of rel) {
if (!nxt[c]) nxt[c] = new Set();
if (!nxt[f]) nxt[f] = new Set();
nxt[f].add(c);
if (!fst[c]) fst[c] = idx++;
if (!fst[f]) fst[f] = idx++;
}
for (let s of brk) {
del(nxt, s);
}
const res = Object.keys(nxt);
if (res.length == 0) return ",";
return res.sort((a, b) => fst[a] - fst[b]).join(",");
}
function del(nxt, s) {
if (nxt[s]) {
const rm = nxt[s];
delete nxt[s];
for (let ss of rm) {
del(nxt, ss);
}
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏
评论记录:
回复评论: