题目
为了达到新冠疫情精准防控的需要,为了避免全员核酸检测带来的浪费,需要精准圈定可能被感染的人群。
现在根据传染病流调以及大数据分析,得到了每个人之间在时间、空间上是否存在轨迹的交叉。
现在给定一组确诊人员编号(X1,X2,X3...Xn) 在所有人当中,找出哪些人需要进行核酸检测,输出需要进行核酸检测的人数。(注意:确诊病例自身不需要再做核酸检测)
需要进行核酸检测的人,是病毒传播链条上的所有人员,即有可能通过确诊病例所能传播到的所有人。
例如:A是确诊病例,A和B有接触、B和C有接触,C和D有接触,D和E有接触。那么B、C、D、E都是需要进行核酸检测的。
输入描述
第一行为总人数N
第二行为确诊病例人员编号 (确证病例人员数量 < N) ,用逗号隔开
接下来N行,每一行有N个数字,用逗号隔开,其中第 i 行的第 j 个数字表示编号 i 是否与编号 j 接触过。0 表示没有接触,1 表示有接触
输出描述
输出需要做核酸检测的人数
补充说明
人员编号从0开始
0 < N < 100
用例
| 输入 | 输出 | 说明 |
|---|---|---|
| 5 1,2 1,1,0,1,0 1,1,0,0,0 0,0,1,0,1 1,0,0,1,0 0,0,1,0,1 | 3 | 编号为1、2号的人员为确诊病例1号与0号有接触,0号与3号有接触,2号4号有接触。所以,需要做核酸检测的人是0号、3号、4号,总计3人要进行核酸检测。 |
思考
图搜索问题,从干扰人员 id 开始递归深度优先搜索接触人员并累计结果计数。矩阵对角线上都是1,只需要搜索对角线一侧的矩阵就行,备忘录visited定义为一维数组根据人员id来标识是否已被访问。
算法过程
1、根据输入构建邻接矩阵,行列都是人员id,索引从0开始,mtx[rowIndex][colIndex] 表示人员rowIndex 与 人员 colIndex 是否接触(1:接触,0:未接触);
2、定义一维 visited 数组用以标记人员是否已被访问,初始化把感染人员标记为true,因为感染人员不加入核酸检测统计;
3、枚举感染人员id开始 dfs,遍历人员id,从0~N-1,排除自己,查询矩阵判断其它人员是否与感染人员接触且未访问,若是则统计结果+1,继续dfs (接触人员id),最终完成所有人员搜索返回统计结果。
参考代码
function solution(lines) {
const arr = lines.trim().split('\n').map(line => line.trim().split(',').map(e => parseInt(e)));
const n = arr[0][0];
const sicks = arr[1];
const mtx = arr.slice(2);
const visited = new Array(n).fill(false); // 标记节点是否被访问
// 将确诊人员标记为已访问(不参与检测)
for (let s of sicks) {
visited[s] = true;
}
let result = 0;
// 从节点u开始DFS,遍历所有可达节点
const dfs = function(u) {
for (let v = 0; v < n; v++) {
if (u === v) continue; // 跳过自身
if (mtx[u][v] && !visited[v]) {
visited[v] = true;
result++;
dfs(v); // 递归搜索相邻节点
}
}
};
// 从每个确诊人员出发进行DFS
for (let s of sicks) {
dfs(s);
}
return result;
}
let inputs = [
`5
1,2
1,1,0,1,0
1,1,0,0,0
0,0,1,0,1
1,0,0,1,0
0,0,1,0,1`,
`5
0
0,1,0,0,0
1,0,0,0,0
0,0,0,1,0
0,0,1,0,1
0,0,0,1,0`
];
inputs.forEach(line => {
console.log(solution(line));
});
3599

被折叠的 条评论
为什么被折叠?



