Skip to content

Jiho daily 21일차 #74

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Jiho/Day20/백준_BFS_단지번호붙이기.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,13 @@ function bfs(x, y) {
console.log(answer.length);
answer.sort((a, b) => a - b);
answer.forEach((item) => console.log(item));


/*
교훈
1. 필요하지 않은 경우의 수에 대해서는 BFS할 필요가 없다.
-> 검증이 필요한 곳에서만 BFS를 쪼개서 할 수 있다.
2. 2차원 배열 bfs (정형화된 패턴)
dx dy로 방향 배열을 선언하고,
nrow, ncol을 만드는 식으로 작성
*/
61 changes: 61 additions & 0 deletions Jiho/Day21/백준_1012_유기농배추.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const fs = require("fs");
const input = fs
.readFileSync(process.platform === "linux" ? "/dev/stdin" : "../input.txt")
.toString()
.trim()
.split("\n");
const TESTCASE = parseInt(input.shift());

const BFS_SearchConnected = (startRow, startCol, N, M, visited, vegi) => {
// # 방향
const dr = [0, 1, 0, -1];
const dc = [1, 0, -1, 0];

const queue = [[startRow, startCol]];
visited[startRow][startCol] = true;

while (queue.length) {
// console.log("Here");
// console.log(queue.shift());
const [row, col] = queue.shift();
for (let i = 0; i < 4; i++) {
const [nrow, ncol] = [row + dr[i], col + dc[i]];
if (
nrow >= 0 &&
nrow < N &&
ncol >= 0 &&
ncol < M &&
!visited[nrow][ncol] &&
vegi[nrow][ncol] === 1
) {
visited[nrow][ncol] = true;
queue.push([nrow, ncol]);
}
}
}
};

// 각각의 TestCase
for (let tc = 0; tc < TESTCASE; tc++) {
// # 입력 처리
const [M, N, K] = input.shift()?.split(" ").map(Number);
const vegi = Array.from(new Array(N), () => new Array(M).fill(0));

for (let i = 0; i < K; i++) {
const [inputCol, inputRow] = input.shift()?.trim().split(" ").map(Number);
vegi[inputRow][inputCol] = 1;
}
// # 방문 처리
const visited = Array.from(new Array(N), () => new Array(M).fill(false));

let answer = 0;
for (let row = 0; row < N; row++) {
for (let col = 0; col < M; col++) {
if (!visited[row][col] && vegi[row][col] === 1) {
answer += 1;
BFS_SearchConnected(row, col, N, M, visited, vegi);
}
}
}
console.log(answer);
}
68 changes: 68 additions & 0 deletions Jiho/Day21/백준_2178.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const fs = require("fs");
const input = fs
.readFileSync(process.platform === "linux" ? "/dev/stdin" : "../input.txt")
.toString()
.trim()
.split("\n");

const [N, M] = input.shift().split(" ").map(Number);
const arr = input.map((subarr) => subarr.trim().split(""));
// # 방향 변수
const dr = [0, 1, 0, -1];
const dc = [1, 0, -1, 0];

const queue = [[0, 0, 1]];
let visited = Array.from(new Array(N), () => new Array(M).fill(false));
visited[0][0] = true;
let min = -1;

while (queue.length) {
const [row, col, cnt] = queue.shift();
console.log(row, col, cnt);
// # 도착 지점 도달
if (row === N - 1 && col === M - 1) {
min = min === -1 ? cnt : Math.min(min, cnt);
}
// # 도착 지점 이동중
else {
let i = 0;
for (i; i < 4; i++) {
const [nrow, ncol] = [row + dr[i], col + dc[i]];
if (
nrow >= 0 &&
nrow < N &&
ncol >= 0 &&
ncol < M &&
arr[nrow][ncol] === "1"
) {
queue.push([nrow, ncol, cnt + 1]);
visited[nrow][ncol] = true;
}
}
}
}
console.log(min);

/*
✍️교훈
처음에는 visited[row][col] = true를 queue에서 꺼냈을 때 했었는데,
Time out Error가 발생함

최적화 필요!!
이때, visited의 뜻 : 해당 점에서 시작하는 모든 경우의 수를 고려했음.
그러면, queue에서 뺐을때 넣는게 아니라, 큐에 넣을때 visited를 바꾸면 최적화 가능
문제는 다음과 같은 상황

1111 [3][3]의 1은 위에서 오는 경로랑 아래로 쭉 돌아서 오는 경로 2가지가 존재.
1001 이렇게, 모든 경우의 수를 판단해서 최소의 값을 구해야 하는게 아닌가? 라는 생각이 들었음
1001 But, BFS의 개념을 이해하면 된다.
1011 BFS는 같은 LEVEL (거리)를 먼저 판단한다.
1110 같은 점에 서로 다른 시점에 들어왔다는 것은 이미 그 점으로의 최소 길이 아님.
즉, 먼저 오는 방향이 제일 짧은 길이일 것임 (방향은 다를 수 있지만, 같은 LEVEL에 도달하는 방향이면 어차피 정답은 같다)

추가
만약에, 모든 경로를 구해야하는 거라면 visited = true는 queue에서 꺼냇을 때 하는게 맞다.


따라서, 최적의 상황은 qeuue에 넣을때 하는것.
*/