[Softeer] Challenge Lv2

세나정·2025년 2월 4일
post-thumbnail

(Lv.2) 나무 공격

https://softeer.ai/practice/9657

풀이

여기에서 배운점 (문법정리)

slice쓰지말고 그냥 0대입해라.

생각보다는 오래 걸렸지만 이냥저냥 Lv.2라 그런지 풀만했던 문제

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

function solution() {
    // 1. 첫 번째 줄: 행(n)과 열(m)
    const [n, m] = input[0].split(' ').map(Number);

    // 2. 지도 데이터
    const maps = [];
    for (let i = 1; i <= n; i++) {
        maps.push(input[i].split(' ').map(Number));
    }

    // 3. 시작점과 끝점
    const start = input[n + 1].split(' ').map(Number);
    const end = input[n + 2].split(' ').map(Number);

    const attackRange = [start, end];
    
    // [사냥꾼 카운팅]
    let hunter = 0;
    for (let i=0; i < n; i++) {
        for(let j=0; j<m; j++) {
            if(maps[i][j] === 1) {
                hunter++
            }
        }
    }

    // 주어진 시작점(start)부터 끝점(end)까지 반복문을 돌며
    // map의 attack의 범위에 대해 j가 1을 만났을 때 
    // 1을 0으로 바꾸어주고 그떄 바꾼 값을 카운팅
    let cnt = 0;
    for (let attck of attackRange) {
       for (let i=attck[0]-1; i < attck[1]; i++) {
            for(let j=0; j<m; j++) {
                if(maps[i][j] === 1) {
                    maps[i][j] = 0;
                    cnt++
                    break;
                }
            }
        }
    }

    console.log(hunter - cnt)
}

solution();

GPT 최적화

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

function solution() {
    // 1. 첫 번째 줄: 행(n)과 열(m)
    const [n, m] = input[0].split(' ').map(Number);

    // 2. 지도 데이터
    const maps = [];
    for (let i = 1; i <= n; i++) {
        maps.push(input[i].split(' ').map(Number));
    }

    // 3. 시작점과 끝점
    const start = input[n + 1].split(' ').map(Number);
    const end = input[n + 2].split(' ').map(Number);

    // 공격 범위 배열
    const attackRange = [start, end];

    // 4. 초기 몬스터 개수 계산 함수
    const countMonsters = () => {
        let count = 0;
        for (const row of maps) {
            for (const cell of row) {
                if (cell === 1) count++;
            }
        }
        return count;
    };

    // 5. 공격 로직 함수
    const attackMonsters = (attackRange) => {
        let defeated = 0;

        for (const [start, end] of attackRange) {
            for (let i = start - 1; i < end; i++) { // 1-based → 0-based 변환
                for (let j = 0; j < m; j++) {
                    if (maps[i][j] === 1) {
                        maps[i][j] = 0; // 몬스터 제거
                        defeated++;
                        break; // 해당 행은 탐색 종료
                    }
                }
            }
        }
        return defeated;
    };

    // 6. 계산
    const initialCount = countMonsters(); // 초기 몬스터 개수
    const defeatedMonsters = attackMonsters(attackRange); // 제거된 몬스터 개수

    // 7. 결과 출력
    console.log(initialCount - defeatedMonsters);
}

solution();

(Lv.2) [한양대 HCPC 2023] Yeah, but How?

완전 어이없는 문제.. 태어나서 예시 TC가 틀리지만 문제가 맞는 경우가 없기에 한참 동안 고쳤었따..

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('');

function solution() {
    
    let ans = [];
    let stack = [];
    
    ans.push(input[0])
    stack.push(input[0])
    
    for(let i=1; i<input.length; i++) {
        if (input[i] === '(') {
            ans.push(input[i]);
            stack.push(input[i]);
        } else {
            stack.pop();

            stack[stack.length-1] === '(' && stack.length%2 === 1 ? ans.push('1+1') : ans.push('1')
            
            ans.push(input[i])   
            if (i !== input.length-1) ans.push('+')
        }
    }

    console.log(ans.join(''))
}

solution()

전형적인 stack문제로 어떻게 stack이 들어가고 어떤 값이 와야하는지 떠올리면 금방 쉽게 풀 수 있음


(Lv.2) Recovering the Region

이 문제에서 배운점 (문법정리)

input을 따올 땐 자료형에 유의 ★

n*n의 false로 된 2차원 배열을 만들고 싶을 때 
따온 input을 바로 넣으면 문자열이라 
1차원의 false배열이 만들어졌었음

소프티어에서 visited를 만들 땐 꼭 n의 값을 parseInt로 바꿔주기

풀이

겁나 어이없음

그냥 각 구역을 나누는 방법을 따지면 되는 거라
아래가 정답이라고 함

그 아래 풀이는 열심히 bfs로 풀었떤 경우

const fs = require('fs')
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
const n = parseInt(input[0]);

for (let i = 0; i < n; i++) {
    console.log(Array(n).fill(i + 1).join(' '));
}
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

function solution() {
    const n = parseInt(input[0]); // 보드 크기
    const maps = [];
    for (let i = 1; i <= n; i++) {
        maps.push(input[i].split(' ').map(Number));   
    }

    // 방문 여부 및 결과 배열 초기화
    let visited = Array.from({ length: n }, () => Array(n).fill(false));
    let result = Array.from({ length: n }, () => Array(n).fill(0));
    let regionId = 1; // 구역 번호 시작

    // 방향 벡터 (상, 우, 하, 좌)
    const dx = [-1, 0, 1, 0];
    const dy = [0, 1, 0, -1];

    // 모든 칸 순회
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            // 방문하지 않은 칸에서 새로운 구역 시작
            if (!visited[i][j]) {
                let queue = [];
                queue.push([i, j]); // 시작점 추가
                visited[i][j] = true;
                result[i][j] = regionId;

                let cells = [[i, j]]; // 현재 구역의 좌표 저장
                let usedNumbers = new Set([maps[i][j]]); // 구역 내 숫자 중복 방지

                while (queue.length) {
                    const [x, y] = queue.shift();

                    // 상, 우, 하, 좌 탐색
                    for (let d = 0; d < 4; d++) {
                        const nx = x + dx[d];
                        const ny = y + dy[d];

                        // 유효한 좌표인지 확인
                        if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
                            // 방문하지 않았고, 숫자가 중복되지 않으면 추가
                            if (!visited[nx][ny] && !usedNumbers.has(maps[nx][ny])) {
                                queue.push([nx, ny]);
                                visited[nx][ny] = true;
                                result[nx][ny] = regionId;
                                cells.push([nx, ny]);
                                usedNumbers.add(maps[nx][ny]);

                                // 구역 크기가 n이면 탐색 종료
                                if (cells.length === n) break;
                            }
                        }
                    }
                }

                regionId++; // 새로운 구역 번호 증가
            }
        }
    }

    // 결과 출력
    result.forEach(row => console.log(row.join(" ")));
}

solution();

연탄의 크기

여기에서 배운점 (문법정리)

오랜만에 보는 max로직

    let max = 0; // 결과값 (최대 배수 카운트)

    // 2부터 배열 최대값까지 반복
    for (let i = 2; i <= largist; i++) {
        let cnt = 0;

        for (let j = 0; j < n; j++) {
            if (charcolls[j] % i === 0) {
                cnt++;
                if (cnt >= max) {
                    max = cnt
                }
            }
        }
    }

풀이

난 그냥 바보똥멍청이다.

결과적으로 가장 큰 차이는 배열 전체를 순회 하느냐 아니면 배열의 가장 작은값~큰값까지 1씩 증가시키며 하는 차이였음

나는 당연하게도 배열의 인덱스에 접근해서 하나하나 상승시켰지만 사실 그게아닌
오름차순 정렬 후 2부터 가장 큰 애까지 반복시키며 거기에서 얼마나 카운트가 되는지 찾는 게 핵심이었다.

위에가 정답 코드 아래가 멍청이 코드라 하자

정답코드

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

function solution() {
    const n = parseInt(input[0]);
    const charcolls = input[1].split(' ').map(Number).sort( (a, b) => a-b );
    
    const largist = charcolls[charcolls.length-1]
    let max = 0; // 결과값 (최대 배수 카운트)

    // 2부터 배열 최대값까지 반복
    for (let i = 2; i <= largist; i++) {
        let cnt = 0;

        for (let j = 0; j < n; j++) {
            if (charcolls[j] % i === 0) {
                cnt++;
                if (cnt >= max) {
                    max = cnt
                }
            }
        }
    }

    console.log(max);
}

solution();

멍청이 코드

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n')

function solution() {
    const n = input[0];
    const charcolls = input[1].split(' ').map(Number).sort((a,b) => a-b);
    // 주어진 숫자 배열에 따라서
    // 각 숫자의 배수가 가장 많은 애의 cnt를 리턴하면 됨 

    let max = 1;
    for(let i=0; i<n; i++) {
        let target = charcolls[i];
        let cnt = 1;

        for (let j=i+1; j<n; j++) {
            if(charcolls[j] % target === 0) {
                cnt++
                if (cnt >= max) {
                    max = cnt;
                } 
                // console.log('max', max)
                // console.log('cnt', cnt)
            }
        }
    }

    console.log(max)
}

solution()

(Lv.2) 진정한 효도

여기에서 배운점

각 인덱스안에 모든 요소들이 같은 값이냐 (반대는 some)

const row = maps[i]
console.log(row.every( v => v === row[0]))

풀이

진짜 겁나 하나도 뭐라는지 너무 꼬이고 꼬인 문제라고 생각이 들었지만 시간이 충분했따면 조금 더 쉽게 접근했을 문제

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

function solution() {
    // 3x3 배열로 입력 받기
    const maps = input.map(line => line.split(' ').map(Number));

    // 세 개의 숫자에서 중간값을 찾아 비용 계산하는 함수
    function calculateCost(a, b, c) {
        const values = [a, b, c];
        const middle = values.sort((x, y) => x - y)[1]; // 중간값
        return Math.abs(middle - a) + Math.abs(middle - b) + Math.abs(middle - c); // 비용 계산
    }

    let res = Infinity; // 결과값 초기화

    // 가로 방향 확인
    for (let i = 0; i < 3; i++) {
        const [firstIndex, secondIndex, thirdIndex] = maps[i];
        if (firstIndex === secondIndex && secondIndex === thirdIndex) {
            console.log(0);
            return;
        } else {
            const tmp = calculateCost(firstIndex, secondIndex, thirdIndex);
            res = Math.min(res, tmp);
        }
    }

    // 세로 방향 확인
    for (let i = 0; i < 3; i++) {
        const col = [maps[0][i], maps[1][i], maps[2][i]];
        if (col[0] === col[1] && col[1] === col[2]) {
            console.log(0);
            return;
        } else {
            const tmp = calculateCost(col[0], col[1], col[2]);
            res = Math.min(res, tmp);
        }
    }

    console.log(res); // 최소 비용 출력
}

solution();

(Lv.2) 금고털이

여기에서 배운점 ★

배열에서 한 개 짜르고 나머지 만들려면

const jew = input.slice(1);

['100 2', '90 1', '70 2'] => ['90 1', '70 2'] 

풀이

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

function solution() {
    let [bag, category] = input[0].split(' ').map(Number);
    let jew = input.slice(1).map(value => value.split(' ').map(Number)).sort( (a, b) => b[1] - a[1]);

    let maxPrice = 0;
    for(let i=0; i<jew.length; i++) {
        let count = jew[i][0];
        let price = jew[i][1];

        let sell = Math.min(bag, count)

        maxPrice += price * sell;
        bag -= sell;

        if(bag === 0) break
    }
    console.log(maxPrice)
}

solution();

생각한대로 쉬웠지만 한 가지 간과한 사실이 있었다

let sell = Math.min(bag, count) 를 통해 누가 빨리 품절되는지 확인이 가능하다는 것

수학적으로 조금 더 다가가면 좋을 것 같다.


(Lv.2) 바이러스

여기에서 배운점

모듈러 연산

MOD = 1000000007;

풀이

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split(' ').map(Number)

const solution = () => {
    let virus = input[0];
    const multiple = input[1];
    const times = input[2];

    const MOD = 1000000007
    
    for(let i=1; i<=times; i++) {
        virus = (virus * multiple) % MOD;
    }

    console.log(virus)
}

solution();

다른 풀이

위 결과도 맞지만 제약조건이 매우 크기떄문에 빠른 제곱 연산을 활용해야 한다고 함

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split(' ').map(BigInt);

function solution() {
    const MOD = 1000000007n; // 모듈러 값
    let [K, P, N] = input; // K: 초기 바이러스 수, P: 증가율, N: 시간

    let result = 1n; // P^N 값을 계산하기 위한 초기값
    let base = P; // P^1부터 계산하기 위한 초기 base 값

    // 빠른 거듭제곱 방식으로 P^N % MOD 계산
    while (N > 0n) {
        if (N % 2n === 1n) {
            result = (result * base) % MOD; // 현재 base를 곱함
        }
        base = (base * base) % MOD; // base를 제곱
        N = N / 2n; // 지수를 반으로 줄임
    }

    // 최종 바이러스 수 계산: (K * P^N) % MOD
    const total = (K * result) % MOD;

    console.log(total.toString()); // 결과 출력
}

solution();

(Lv.2) 8단 변속기

여기에서 배운점

배열을 비교할 땐 stringify를 사용해야만함

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split(' ').map(Number)

function solution() {
    const ascending = [1, 2, 3, 4, 5, 6, 7, 8];
    const descending = [8, 7, 6, 5, 4, 3, 2, 1];

    
    if (JSON.stringify(input) === JSON.stringify(ascending)) {
        console.log("ascending");
    } else if (JSON.stringify(input) === JSON.stringify(descending)) {
        console.log("descending");
    } else {
        console.log("mixed");
    }

}

solution()

풀이

맨 처음에 every, 그리고 sort를 이용하여 풀다가 오답이 나왔는데 그 이유가 stringfy를 해주지 않아서 그런 것 같다


(Lv.2) 장애물 인식 프로그램 ★★★

여기에서 배운점

BFS 덩어리 찾기

★★★ 덩어리 찾을 때는 무조건 이중포문안에!!!

=> 각각의 출발점을 조사할 때도 필요하니까

위에 기존 코드의 모든 작업들은 이중포문 안에서 해결할 수 있음

내 기존 코드

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n')

function solution() {
    const n = parseInt(input[0])
    let ans = [];
    
    let maps = [];
    for (let i=1; i <= n; i++) {
        maps.push(input[i].split('').map(Number))
    }
    
    let visited = [];
    for(let i=0; i<n; i++) visited.push(new Array(n).fill(false))

    let startPos = [];
    for(let i=0; i<n; i++) {
        if (startPos.length === 1) break;
        for(let j=0; j<n; j++) {
            if(maps[i][j] === 1) {
                startPos.push([i,j]);
                break;
            }
        }
    }


    
    visited[startPos[0][0]][startPos[0][1]] = true;

    // maps[startPos[0][0]][startPos[0][1]] = 2;
    
    let queue = [];
    queue.push([startPos[0][0], startPos[0][1]])


    const dx = [-1, 0, 1 ,0];
    const dy = [0, 1, 0, -1];

    let junk = 2;
    let reStartPos = [];
    while(queue.length) {
        const [x, y] = queue.shift();

        maps[x][y] = junk;
        let cnt = 0;

        
        for(let i=0; i<4; i++) {
            let nx = x + dx[i];
            let ny = y + dy[i];
            
            if (nx >= 0 && nx < n && ny >= 0 && ny < n && !visited[nx][ny] && maps[nx][ny] === 1) {
                cnt++;
                visited[nx][ny] = true;
                // maps[nx][ny] = maps[x][y] + 1
                maps[nx][ny] = junk

                queue.push([nx, ny])
            }        
        }

        if(!queue.length) {
            for(let i=0; i<n; i++) {
                if (queue.length === 1) break;
                for(let j=0; j<n; j++) {
                    if(maps[i][j] === 1) {
                        queue.push([i,j]);
                        break;
                    }
                }
            }
        }

        junk++;
    }
    
    console.log('maps', maps)
}

solution()

풀이

풀이코드 1

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

function solution() {
    const n = parseInt(input[0]);
    
    let maps = [];
    for (let i = 1; i <= n; i++) {
        maps.push(input[i].split('').map(Number));
    }
    
    let visited = Array.from({ length: n }, () => Array(n).fill(false));

    const dx = [-1, 0, 1, 0];
    const dy = [0, 1, 0, -1];

    let junk = 2; // 덩어리마다 다른 숫자로 표시
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            if (maps[i][j] === 1 && !visited[i][j]) {
                let queue = [[i, j]];
                visited[i][j] = true;
                maps[i][j] = junk;

                while (queue.length) {
                    const [x, y] = queue.shift();

                    for (let k = 0; k < 4; k++) {
                        let nx = x + dx[k];
                        let ny = y + dy[k];

                        if (nx >= 0 && nx < n && ny >= 0 && ny < n && !visited[nx][ny] && maps[nx][ny] === 1) {
                            visited[nx][ny] = true;
                            maps[nx][ny] = junk;
                            queue.push([nx, ny]);
                        }
                    }
                }
                junk++; // 다음 덩어리는 새로운 숫자로 표시
            }
        }
    }
    
    console.log('maps', maps);
}

solution();

풀이

오랜만에 제대로된 BFS의 덩어리 문제를 찾았다

하지만 처음엔 while안에다가 이중 포문을 넣어 뭐가 문제인지 모르는 체로 계속헤매다가 예전에 풀었던 덩어리 찾기에서 힌트를 얻고 이중 포문안에 넣는 방법을 떠올렸다

생각해보면 당연히 이중포문을 통해 앞에서부터 접근한다면 여러가지 전처리 기능을 바로바로 해결할 수 있었던 장점이 있는 것 같다

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

function solution() {
    const n = parseInt(input[0]);
    
    let maps = [];
    for (let i = 1; i <= n; i++) {
        maps.push(input[i].split('').map(Number));
    }
    
    let visited = [];
    for (let i = 0; i < n; i++) {
        visited.push(new Array(n).fill(false));
    }

    let queue = [];
    const dx = [-1, 0, 1, 0];
    const dy = [0, 1, 0, -1];

    let junk = 2;
    let cnt = 1;
    let ans = [];

    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            if (maps[i][j] === 1 && !visited[i][j]) {
                queue.push([i, j]);
                visited[i][j] = true;
                maps[i][j] = junk;

                while (queue.length) {
                    const [x, y] = queue.shift();

                    for (let k = 0; k < 4; k++) {
                        let nx = x + dx[k];
                        let ny = y + dy[k];
                        if (nx >= 0 && nx < n && ny >= 0 && ny < n && !visited[nx][ny] && maps[nx][ny] === 1) {
                            cnt++;
                            visited[nx][ny] = true;
                            maps[nx][ny] = junk;
                            queue.push([nx, ny]);
                        }
                    }
                }

                ans.push(cnt); // 단지의 크기를 ans에 추가
                junk++;
                cnt = 1; // 다음 단지를 위해 카운트 초기화
            }
        }
    }

    ans.sort( (a, b)  => a-b)
    console.log(ans.length); // 단지의 수 출력
    for (let i = 0; i < ans.length; i++) {
        console.log(ans[i]); // 각 단지의 크기 출력
    }
}

solution();

우선 코드는 위와 같고

  1. 늘 하던대로 maps와 visited를 작성하고
  2. queue 뿐만 아니라 dx, dy를 선언한다
  3. 다른 덩어리로 분리되기 위해 junk 변수를 선언한 후 카운트 (당연히 1부터)될 변수를 선언한 뒤에
  4. ★ 이중 포문을 돌며 1을 만나는 순간부터 시작하여 해당 부분 true처리 그리고 시작점도 junk로 2로 바꾸어 시작처리를 한다
  5. 그리고 난 후에 queue에 넣어 하던대로 bfs를 실행하면 된다 여기에서 처리를 바꾸는 처리를 할 때마다 cnt의 값을 올려주고
  6. 그 값을 if문을 벗어나기 전에 ans 배열에 넣어주고, junk값을 올려주고 다시 cnt를 초기화 하면 된다
  7. 그리고 바보 같이 오름차순으로 정렬인데 나는 그걸 까먹고 계속 제출하고 있었다

(Lv.2) 지도 자동 구축

여기에서 배운점

제곱은 pow

1 4 9 25 -> (2^k + 1)^2 (옛날에 많이봄)

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim();

function solution() {
    const n = parseInt(input)
    
    console.log(Math.pow(Math.pow(2, n)+1, 2))
}

solution()

징검다리 비밀메뉴 조립라인

(Lv.2) 비밀메뉴

엥 그냥 포함관계 확인하면 되는 너무 쉬운 문제..

풀이

// 첫쨰줄 -> 비밀 버튼 갯수, 버튼 조작 갯수, 최대값
// 두번쨰줄 -> 조작 방법
// K -> 버튼 갯수 

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n')

function solution() {
    const [m, n, k] = input[0].split(' ').map(Number)
    const method = input[1].split(' ').join('')
    const controll = input[2].split(' ').join('')

    console.log(controll.includes(method) ? 'secret' : 'normal')    
}

solution()

(Lv.2) GBC

여기에서 배운점

이 문제는 그리디에서 투 포인터 기법

두 개의 배열이 주어졌을 때 반복문으로 i와 j를 증가하는 것이 아닌 조건에 따라 증가시키는 것

풀이

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n')

function solution() {
    const [n, m] = input[0].split(' ').map(Number)
    
    let targetCos = [];
    for (let i=1; i < n+1; i++) targetCos.push(input[i].split(' ').map(Number))

    let testCos = [];
    for (let i=n+1; i < input.length; i++) testCos.push(input[i].split(' ').map(Number))

    // (초기) 타겟의 거리 설정
    let i = 0;
    let targetDist = targetCos[i][0];

    // (초기) 테스트의 거리 설정
    let j = 0;
    let testDist = testCos[j][0];

    // max값을 저장할 변수
    let maxSpeed = 0;

    // 둘 중 하나가 끝나면 끝
    while(i < n && j < m) {
        // 타겟의 스피드 설정
        let targetSpeed = targetCos[i][1];
        // 테스트의 스피드 설정
        let testSpeed = testCos[j][1];

        // 테스트가 더 크면 
        if (testSpeed > targetSpeed) {
            // 초과한 거리만큼 max값을 계산하여 할당
            maxSpeed = Math.max(maxSpeed, testSpeed - targetSpeed);
        }

        // test의 길이가 더 길 경우
        if (testDist > targetDist) {
            // 남은 테스트의 길이 설정
            testDist = testDist - targetDist;
            // 다음 타겟을 위한 i값 증가
            i++
            // 다음 타겟값 설정
            if (i < n) targetDist = targetCos[i][0];
        } else if (targetDist > testDist) {
            // target의 길이가 더 길 경우 (마찬가지)
            targetDist = targetDist - testDist;
            j++
            if (j < m) testDist = testCos[j][0];
        } else {
            // 둘 다 동일시 둘다 증가
            i++
            j++
            if (i < n) targetDist = targetCos[i][0];
            if (j < m) testDist = testCos[j][0];
        }
    }
    console.log(maxSpeed)
}

solution()

어떻게 보면 쉽고 어떻게 보면 어려웠던 것 같음 (졸려서 그런가)

두 개의 포인터를 각각 놓고 값을 증가시키면서
다음 타겟의 값을 지정해주던
다음 테스트의 값을 지정해주며 나아가면 됨

max관련해서는 더욱 꼼꼼히 살펴봐야할 것 같음


(Lv.2) 회의실 예약 (재직자 대회)

그냥 Map을 한번 써보기 위해 간단하게 풀은 문제..
재직자 대회문제는 그냥 놀자식인지 굳이 안 풀어도 되거나 padStart를 쓰는 문제가 많은 것 같다

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

function solution() {
    const [n, m] = input[0].split(' ').map(Number);

    // 9~18까지 비교용 배열
    const START_TIME = 9;
    const END_TIME = 18;

    // 회의실 이름 저장
    let 회의실 = [];
    for (let i = 1; i <= n; i++) 회의실.push(input[i]);

    // 회의실 별 예약 정보 저장 (Map 활용)
    let 회의실맵 = new Map(회의실.map(회의실이름 => [회의실이름, []]));

    // 예약 정보 저장
    let 예약정보 = [];
    for (let i = n + 1; i < input.length; i++) {
        let [회의실이름, start, end] = input[i].split(' ');
        start = Number(start);
        end = Number(end);
        회의실맵.get(회의실이름).push([start, end]);
    }

    // **출력 포맷 맞추기**
    let result = [];

    // 회의실 이름을 오름차순 정렬 후 처리
    let 정렬된회의실 = [...회의실맵.keys()].sort();

    for (let room of 정렬된회의실) {
        result.push(`Room ${room}:`);
        let 예약된시간 = 회의실맵.get(room);

        // 예약된 시간 정렬
        예약된시간.sort((a, b) => a[0] - b[0]);

        // 빈 시간대 찾기
        let availableTimes = [];
        let prevEnd = START_TIME;

        for (let [start, end] of 예약된시간) {
            if (prevEnd < start) {
                availableTimes.push(`${String(prevEnd).padStart(2, '0')}-${String(start).padStart(2, '0')}`);
            }
            prevEnd = end;
        }

        // 마지막 시간 이후의 빈 시간 체크
        if (prevEnd < END_TIME) {
            availableTimes.push(`${String(prevEnd).padStart(2, '0')}-${String(END_TIME).padStart(2, '0')}`);
        }

        // 예약 가능 시간이 없는 경우
        if (availableTimes.length === 0) {
            result.push("Not available");
        } else {
            result.push(`${availableTimes.length} available:`);
            result.push(...availableTimes);
        }
        
        // 마지막 회의실인지 확인 후, 구분선 추가 여부 결정
        if (room !== 정렬된회의실[정렬된회의실.length - 1]) {
            result.push("-----");
        }
    }

    // 결과 출력
    console.log(result.join("\n"));
}

solution();
profile
기록, 꺼내 쓸 수 있는 즐거움

0개의 댓글