[연습문제] 19. 83 ~ 85 bfs/dfs
bfs, dfs 좀 그만 쫄자..!!
83. 후위 순회
컴퓨터공학과에 들어간 사촌 동생이 후위 순회를 궁금해한다. 트리가 주어졌을 때, 후위 순회하며 방문했던 노드를 산출해주는 프로그램을 작성하시오. 입력은 노드가 추가되는 순번대로 명시된 문자열이 주어지며, 트리를 만들어 갈 때 작은 값은 왼쪽으로, 큰 값은 오른쪽으로 붙여가며 만든다. 왼쪽 - 오른쪽 - 루트 순으로 후위 순회하며 방문한 노드를 배열에 저장하고 그 결화를 반환한다.
function Node(value) {
this.value = value;
this.left = null;
this.right = null;
}
function BinarySearchTree() {
this.root = null;
}
BinarySearchTree.prototype.insert = function (value) {
this.root = this._insertNode(this.root, value);
};
BinarySearchTree.prototype._insertNode = function (node, value) {
if (node === null) {
node = new Node(value);
} else if (value < node.value) {
node.left = this._insertNode(node.left, value);
} else if (value > node.value) {
node.right = this._insertNode(node.right, value);
}
return node;
};
BinarySearchTree.prototype.postOrderTraverse = function (node, array) {
if (node === null) {
return;
}
this.postOrderTraverse(node.left, array);
this.postOrderTraverse(node.right, array);
array.push(node.value)
};
function answer(str) {
let result = [];
// 구현
let tree = new BinarySearchTree();
for (let i = 0; i < str.length; i++) {
tree.insert(str[i]);
}
tree.postOrderTraverse(tree.root, result);
// 구현 종료
return result;
}
let input = [
// TC : 1
"ABC",
"FBADCEGIH",
"CBAEDFG",
];
for (let i = 0; i < input.length; i++) {
process.stdout.write(`#${i + 1}`);
console.log(answer(input[i]));
}
// #1[ 'C', 'B', 'A' ]
// #2[
// 'A', 'C', 'E',
// 'D', 'B', 'H',
// 'I', 'G', 'F'
// ]
// #3[
// 'A', 'B', 'D',
// 'G', 'F', 'E',
// 'C'
// ]
84. 바이러스
최근 웜 바이러스가 네트워크를 통해 전파되고 있는데, 한 컴퓨터라도 이 바이러스에 걸리면 컴퓨터와 연결되어 있는 모든 컴퓨터는 바이러스에 걸리게 된다. 현재 PC에 설정된 네트워크 기준으로, 한대의 PC에 바이러스가 걸렸을 때 총 몇 대의 PC가 바이러스에 걸릴지 계산하는 프로그램을 작성하시오. 예를 들어 7번까지의 PC가 있고, 1,2,3,5,6번 PC는 1번 네트워크, 4,7번 PC는 2번 네트워크로 구성되어 있을 때, 1번 pc가 바이러스에 걸리면 총 5대의 pc가 바이러스에 걸리게 된다. 입력은 pc의 총 대수와, pc와 pc가 연결된 네트워크 정보가 배열로 입력된다. 웜 바이러스에 감염된 pc는 무조건 1번으로 고정될 때, 바이러스에 걸리는 총 pc의 대수를 계산하여 반환하시오
function Graph() {
this.edge = {};
this.visited = {};
}
Graph.prototype.addVertex = function (v) {
this.edge[v] = [];
this.visited[v] = false;
};
Graph.prototype.addEdge = function (v1, v2) {
this.edge[v1].push(v2);
this.edge[v2].push(v1);
};
Graph.prototype.dfs = function (vertex) {
if (this.visited[vertex]) return;
this.visited[vertex] = true;
let neighbors = this.edge[vertex];
for (let i = 0; i < neighbors.length; i++) {
this.dfs(neighbors[i]);
}
};
function answer(v, e_list) {
let result = 0;
// 구현
let g = new Graph();
// 1. addVertex : PC 추가
for (let i = 1; i <= v; i++) {
g.addVertex(i);
}
// 2. addEdge : 네트워크 연결 (무방향)
for (let i = 0; i < e_list.length; i++) {
let e = e_list[i];
g.addEdge(e[0], e[1]);
}
// 3. dfs 방문한 pc를 업데이트
g.dfs(1);
// 4. visited[vertex] > 방문 ? true : false
for (let vertex in g.visited) {
result += g.visited[vertex] ? 1 : 0;
}
// 구현 종료
return result;
}
let input = [
// TC : 1
[
7,
[
[1, 2],
[2, 3],
[1, 5],
[1, 5],
[5, 2],
[5, 6],
[4, 7],
],
],
[
10,
[
[8, 6],
[5, 7],
[9, 10],
[7, 4],
[1, 8],
[5, 10],
[7, 2],
],
],
[
10,
[
[6, 9],
[9, 4],
[4, 8],
[9, 7],
[6, 8],
[10, 1],
[10, 9],
],
],
];
for (let i = 0; i < input.length; i++) {
process.stdout.write(`#${i + 1} `);
console.log(answer(input[i][0], input[i][1]));
}
// #1 5
// #2 3
// #3 7
85. 미로 찾기
친구가 제주도 미로 공원에서 들어갔는데 1시간째 못 빠져 나오고 있다. 친구를 도와 최단거리로 미로를 빠져나오는 경로를 구하는 프로그램을 작성하시오. 미로 공원은 정사각형 형태이며, 길 0과 벽 1로 이루어진 X축 문자열 정보가 Y축 개수만큼 주어진다. 정사각형으로 이루어진 2차원 미로 지도의 입구는 왼쪽 하단이고, 출구는 오른쪽 상단이다. 최단 경로로 입구에서 출구를 나갈 때 거쳐야 하는 길의 개수를 반환하시오. 만약 출구로 갈 수 있는 길이 없다면 -1을 반환한다.
function Node(x, y, c) {
this.x = x;
this.y = y;
this.c = c;
}
function answer(input) {
let result = -1;
// 구현
// 문자열 -> map(정수: 0, 1)
let map = [];
let size = input.length;
for (let i = 0; i < size; i++) {
map[i] = [];
for (let j = 0; j < size; j++) {
map[i][j] = Number(input[i][j]);
}
}
// 시작, 끝 포인트 설정
let s = [0, size - 1];
let e = [size - 1, 0];
// 시작 > Queue
let queue = [];
queue.push(new Node(s[0], s[1], 1));
// Queue 순회 == 끝 break
while (queue.length !== 0) {
let v = queue.shift();
if (v.x < 0 || v.y < 0 || v.x >= size || v.y >= size) continue;
if (map[v.y][v.x] === 1) continue;
if (v.x == e[0] && v.y == e[1]) {
result = v.c;
break;
}
map[v.y][v.x] = 1; // 지나왔으니까 벽으로 만듦
let dir = [
[1, 0],
[0, 1],
[-1, 0],
[0, -1],
];
for (let i = 0; i < dir.length; i++) {
queue.push(new Node(v.x + dir[i][0], v.y + dir[i][1], v.c + 1));
}
}
// 구현 종료
return result;
}
let input = [
// TC : 1
["00110", "00010", "00110", "00000", "01011"],
["00110", "00010", "00110", "00010", "01011"],
];
for (let i = 0; i < input.length; i++) {
process.stdout.write(`#${i + 1} `);
console.log(answer(input[i]));
}
// #1 9
// #2 -1
예전에는 엄두도 안나서 풀이 못보고 넘겼었는데, 오늘은 완벽하게 이해했다! 다만, 내가 스스로 짜기에는 아직 너무 생각하는 힘이 부족한 것 같다. map을 만드는 이중 for문 기억하고, 방향 증가할 때 dir 변수와 for문 템플릿 기억하기!