logic
- NxN크기의 영역에서 물의 높이는 0이상이다.
- 영역에서 지역의 높이는 2이상 100이하이다.
- 물에 잠기지 않는 "지역" 은
지역의 높이 > 물의 높이
인 곳- 물에 잠기지 않는 "영역" 은
상하좌우가 인접한 경우 하나
로 친다.- bfs로 방문여부(0==방문X,1==방문)와 잠김여부 (0==잠김,1==안잠김)로 방문하지 않았으면서 잠기지 않는 영역의 개수를 세준다.
방문 개수를 세줄 때 deque에 넣어 모두 방문할때까지 popleft를 해주기파이썬 deque 대신 배열을 reverse해주고, pop해주고, 다시 reverse해주기- 모든 물의 높이를 고려할 필요가 없으므로 최고 물 높이를 입력값을 받아올 때 구한다.
- 최고 물 높이는 가장 높은 지역의 높이 -1이다. (같으면 모든 지역이 잠기므로)
// https://www.acmicpc.net/problem/2468
interface Graph {
items: Array<Array<number>>;
count: number;
max_num_arr: Array<number>;
max_num: number;
visited?: Array<Array<number>>;
x_y_idx?: Array<number>;
x?: number;
y?: number;
}
const directions = [
[0, 1],
[0, -1],
[1, 0],
[-1, 0],
];
const dfs=(dq:Array<Array<number>>,a:Graph["items"],fld:Graph["items"],v:Graph["items"])=>{
while (dq.length > 0) {
const popLeft: Array<number> = dq[0];
let x: number = popLeft[0];
let y: number = popLeft[1];
dq.splice(0,1);
for (let k = 0; k < 4; k++) {
let nx = x + directions[k][0];
let ny = y + directions[k][1];
if (0 <= nx && nx < a.length && ny >= 0 && ny < a.length) {
if (fld[nx][ny] == 1 && v[nx][ny] === 0) {
v[nx][ny] = 1;
dq.push([nx, ny]);
}
}
}
}
}
//높이그래프 순회하면서 높이에 따른 잠긴 지역표시
const sunk = (area: Graph["items"], max_height: Graph["max_num"]) => {
let h: number = max_height - 1;
let flooded: Graph["items"];
const ans_arr: Array<number> = [];
while (h >= 0) {
//잠김 = 0, 잠기지 않음 =1
flooded = area.map((v) => {
return v.map((itm) => {
return itm > h ? 1 : 0;
});
});
h--;
const visited: Graph["visited"] = [...area].map((v) => [...v].fill(0));
let cnt: number = 0;
for (let i = 0; i < area.length; i++) {
for (let j = 0; j < area.length; j++) {
if (flooded[i][j] == 1 && visited[i][j] == 0) {
let q: Array<Array<number>> = [];
q.push([i, j]);
dfs(q, area, flooded, visited);
visited[i][j] = 1;
cnt++;
}
}
}
ans_arr.push(cnt);
}
return Math.max(...ans_arr);
};
//input값들 받아오기 & 에러처리
const sol = () => {
const n: string | null = prompt("지역의 개수 NxN개에서 N을 입력해주세요:");
const N: Graph["count"] | null = n ? parseInt(n) : null;
const max_arr: Graph["max_num_arr"] = [];
const heights: Graph["items"] = [];
let max_a: Graph["max_num"] = 1;
if (n && N && !n.includes(" ")) {
for (let i = 0; i < N; i++) {
const h: string | null = prompt(`${i + 1}줄에서 지역의 높이`);
h ? heights.push(h.split(" ").map((v) => parseInt(v))) : null;
max_arr.push(Math.max(...heights[i]));
if (heights[i].length !== N) {
return console.log("구역의 높이 개수가 불일치 합니다.");
}
}
if (heights.length === N && heights.map((v) => v.length == N)) {
max_a = Math.max(...max_arr);
} else {
return console.log("구역의 높이 개수가 불일치 합니다.");
}
} else {
console.log("지역의 개수가 부적합합니다.");
return;
}
let count: number = 0;
console.log(sunk(heights, max_a));
};
sol(); 6
8 9 5 2 7
output:5
--------
* test2
7
9 9 9 9 9 9 9
9 2 1 2 1 2 9
9 1 8 7 8 1 9
9 2 7 9 7 2 9
9 1 8 7 8 1 9
9 2 1 2 1 2 9
9 9 9 9 9 9 9
output:6
*/
Array<Array<number>>
식으로 중첩되는 타입 중복을 피하기 위해서 그래프 인터페이스를 만들어서 사용했다.while(deque에 값이 있을때)
라고 생각했는데, 자바스크립트 코드에서는 빈배열
이 아니라 배열의 길이
로 접근해야했다.slice함수
로 앞에 원본 배열을 복사해줘서 splice해줬던 값을 할당해주면 되지 않았나 싶었다. 근데 얕은 복사라서 그런지 삭제가 안됐다.