일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 알고리즘
- js코테
- 익스프레스
- 리액트
- 백준
- JS
- 백준구현
- dp알고리즘
- 리액트커뮤니티
- 백준알고리즘
- 코딩테스트
- 백준nodejs
- 포이마웹
- 프로그래머스코테
- CSS
- HTML
- 프로그래머스JS
- 코테
- 리액트댓글기능
- 몽고DB
- JS프로그래머스
- 백준구현문제
- 백준골드
- 다이나믹프로그래밍
- 자바스크립트
- 백준js
- HTML5
- 프로그래머스
- css기초
- 안드로이드 스튜디오
- Today
- Total
개발새발 로그
[JS] 백준 15683 : 감시 본문
https://www.acmicpc.net/problem/15683
15683번: 감시
스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감
www.acmicpc.net
📋풀이방법
1. CCTV가 있는 곳의 좌표를 모두 저장한다
2. DFS를 이용해서 CCTV의 넘버에 따라 각각의 방향으로 뻗어나간다.
-1번이면 4개의 방향 -> DFS 4개
- 2번이면 2개의 방향 -> DFS 2개
-3번이면 4개의 방향 -> DFS 4개
- 4번이면 4개의 방향 -> DFS 4개
- 5번이면 1개의 방향 -> DFS 1개
-각 방향으로 뻗어나가는 DFS를 모두 구해야한다.
3. 각 CCTV의 방향을 #으로 바꿔줘야한다.
-CCTV마다 각각 보는 방향이 다르므로 함수를 만들어서 각각 다른 방향을 보는 것을 해결했다.
-각 열 또는 행에 6이 있으면 함수를 멈추고 0이 아닌 cctv가있으면 #으로 바꾸지않아야한다.
-그 이외에는 #으로 한 방향을 모두 칠해준다.
🤟내 제출
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim();
input=input.replace(/\r/g,"").split("\n");
let [N,M]=input.shift().split(" ").map(Number);
let arr=[]
for(var i=0;i<N;i++){
arr.push(input.shift().split(" ").map(Number));
}
let cctv=[];
for(var i=0;i<N;i++){
for(var j=0;j<M;j++){
if(arr[i][j]!=0 && arr[i][j]!=6) cctv.push([i,j,arr[i][j]]);
}
}
function checkRight(arr_t,y,x){
for(var i=x+1;i<M;i++){
if(arr_t[y][i]==6) return;
if(arr_t[y][i]!=0) continue;
arr_t[y][i]=-1;
}
}
function checkLeft(arr_t,y,x){
for(var i=x-1;i>=0;i--){
if(arr_t[y][i]==6) return;
if(arr_t[y][i]!=0) continue;
arr_t[y][i]=-1;
}
}
function checkUp(arr_t,y,x){
for(var i=y-1;i>=0;i--){
if(arr_t[i][x]==6) return;
if(arr_t[i][x]!=0) continue;
arr_t[i][x]=-1;
}
}
function checkDown(arr_t,y,x){
for(var i=y+1;i<N;i++){
if(arr_t[i][x]==6) return;
if(arr_t[i][x]!=0) continue;
arr_t[i][x]=-1;
}
}
let min=10000;
function DFS(L,tmap,cc){
if(L == cc.length) {
let count=0;
for(var i=0;i<N;i++){
for(var j=0;j<M;j++){
if(tmap[i][j]==0) count++;
}
}
min = Math.min(min,count);
return;
}
let [y,x,ccNum]=cc[L];
let temp=[];
if(ccNum==1){
temp=tmap.map(x=>[...x]);
checkLeft(temp,y,x);
DFS(L+1,temp,cc);
temp=tmap.map(x=>[...x]);
checkRight(temp,y,x);
DFS(L+1,temp,cc);
temp=tmap.map(x=>[...x]);
checkUp(temp,y,x);
DFS(L+1,temp,cc);
temp=tmap.map(x=>[...x]);
checkDown(temp,y,x);
DFS(L+1,temp,cc);
}
else if(ccNum==2){
temp=tmap.map(x=>[...x]);
checkLeft(temp,y,x);
checkRight(temp,y,x);
DFS(L+1,temp,cc);
temp=tmap.map(x=>[...x]);
checkUp(temp,y,x);
checkDown(temp,y,x);
DFS(L+1,temp,cc);
}else if (ccNum == 3) {
temp=tmap.map(x=>[...x]);
checkLeft(temp, y,x);
checkUp(temp,y,x);
DFS(L+1, temp, cc);
temp=tmap.map(x=>[...x]);
checkUp(temp,y,x);
checkRight(temp,y,x);
DFS(L+1, temp, cc);
temp=tmap.map(x=>[...x]);
checkRight(temp,y,x);
checkDown(temp,y,x);
DFS(L+1, temp, cc);
temp=tmap.map(x=>[...x]);
checkDown(temp,y,x);
checkLeft(temp,y,x);
DFS(L+1, temp, cc);
}
else if (ccNum == 4) {
temp=tmap.map(x=>[...x]);
checkRight(temp,y,x);
checkLeft(temp, y,x);
checkUp(temp,y,x);
DFS(L+1, temp, cc);
temp=tmap.map(x=>[...x]);
checkUp(temp,y,x);
checkLeft(temp,y,x);
checkDown(temp,y,x);
DFS(L+1, temp, cc);
temp=tmap.map(x=>[...x]);
checkRight(temp,y,x);
checkLeft(temp,y,x);
checkDown(temp,y,x);
DFS(L+1, temp, cc);
temp=tmap.map(x=>[...x]);
checkDown(temp,y,x);
checkRight(temp,y,x);
checkUp(temp,y,x);
DFS(L+1, temp, cc);
}else if(ccNum==5){
temp=tmap.map(x=>[...x]);
checkRight(temp,y,x);
checkLeft(temp, y,x);
checkUp(temp,y,x);
checkDown(temp,y,x);
DFS(L+1, temp, cc);
}
}
DFS(0,arr,cctv)
console.log(min)
💢어려웠던 점
1. CCTV마다 바로보는 방향이 다른 것을 해결하지 못했다.
-CCTV 좌표를 기준으로 상하좌우를 #으로 색칠하는 함수를 통해 해결해야했다.
2. DFS로 뻗어나갈 때 CCTV가 2개이상일 때는 각 4방향 또는 2방향, 1방향 에 대한 모든 경우의 수를 어떻게 계산해야하는지 파악하지 못했다.
-만약 1번 과 2번 CCTV가 있다면
- 1번의 4방향 2번의 2방향 4*2=8가지의 경우의 수를 모두 구해야한다.
-이는 DFS를 각각의 볼 수 있는 방향에 따라 map을 복사하면서 모두 뻗어 나가주면 된다.
-예시 4번일때
if (ccNum == 4) {
temp=tmap.map(x=>[...x]);
checkRight(temp,y,x);
checkLeft(temp, y,x);
checkUp(temp,y,x);
DFS(L+1, temp, cc);
temp=tmap.map(x=>[...x]);
checkUp(temp,y,x);
checkLeft(temp,y,x);
checkDown(temp,y,x);
DFS(L+1, temp, cc);
temp=tmap.map(x=>[...x]);
checkRight(temp,y,x);
checkLeft(temp,y,x);
checkDown(temp,y,x);
DFS(L+1, temp, cc);
temp=tmap.map(x=>[...x]);
checkDown(temp,y,x);
checkRight(temp,y,x);
checkUp(temp,y,x);
DFS(L+1, temp, cc);
}
'알고리즘' 카테고리의 다른 글
[JS]백준 14890 : 경사로 (0) | 2023.07.10 |
---|---|
[JS] 백준 17144번 : 미세먼지 안녕! (0) | 2023.07.09 |
[JS] 백준 2573 : 빙산 (0) | 2023.07.07 |
[JS] 백준 14891 : 톱니바퀴 (0) | 2023.07.06 |
[JS] 백준 12100 : 2048(Easy) (0) | 2023.07.05 |