개발자 톡

연습문제 톡 [21년 재직자 대회 예선] 좌석 관리

JS

등록일
2024-11-15 20:03:59
조회수
27
작성자
vavoya6324

그냥 하나하나 순수하게 전부 검사해야합니다.


const fs = require('fs');
const input = fs.readFileSync('input.txt', 'utf8').trim().split(/\n+/);
const [N, M, _] = input[0].trim().split(/\s+/).map(Number);
const table = Array.from({length: N}, () => Array.from({length: M}, () => false))
const tableIdLog = {}

const problems = input.slice(1)
let output = ''

function processOut(outId) {
    // 이용 기록이 있으면
    if (outId in tableIdLog) {
        const [n, m] = tableIdLog[outId]
        // 자리가 없으면 => 이미 떠남
        if (n === -1 && m === -1) {
            return `${outId} already left seat.`
        }
        else {
            // 자리 비워두기
            table[n][m] = false
            // 로그 변경
            tableIdLog[outId] = [-1, -1]
            return `${outId} leaves from the seat (${n + 1}, ${m + 1}).`
        }
    }
    else {
        return `${outId} didn't eat lunch.`
    }
}

function findSafetyTable() {
    // 지정 좌석으로 부터
    let [safeN, safeM] = [0, 0]
    let maxValue = -1

    let isFull = true

    table.forEach((row, n) => {
        row.forEach((isUsing, m) => {
            // 사용중이 아니어야하고, 상하좌우가 사용중이면 안됨.
            // 사용중인것의 not 연산 => 자리가 존재하고 사용 중인 경우에 대한 반대. 자리가 없거나, 사용중이 아니거나
            if (isUsing === false && (
                !(table[n][m + 1] === true)
                && !(table[n][m - 1] === true)
                && !(table[n-1] && table[n-1][m] === true )
                && !(table[n+1] && table[n+1][m] === true )
            )) {
                isFull = false
                let min = Number.MAX_SAFE_INTEGER

                // 현재 빈 좌석으로 부터 사용 좌석 까지의 안전도 계산
                for (const id in tableIdLog) {
                    const [useN, useM] = tableIdLog[id]
                    if (useN !== -1 && useM !== -1) {
                        const newMin = (useN - n) ** 2 + (useM - m) ** 2
                        min = Math.min(min, newMin)
                    }
                }

                // 현재까지 제일 안전하다고 판단된 빈 좌석과 비교
                // 그냥 더 안전하면
                if (maxValue < min) {
                    maxValue = min
                    safeM = m
                    safeN = n
                }
                // 같으면, 조건에 맞게 처리
                else if (maxValue === min) {
                    if (n < safeN) {
                        safeN = n
                        safeM = m
                    }
                    else if (n === safeN && m < safeM){
                        safeN = n
                        safeM = m
                    }
                }

            }
        })
    })

    return [safeN, safeM, isFull]
}

function processIn(addId) {
    // 이용 기록이 있으면
    if (addId in tableIdLog) {
        const [n, m] = tableIdLog[addId]
        // 자리가 없으면 => 이미 떠남
        if (n === -1 && m === -1) {
            return `${addId} already ate lunch.`
        }
        else {
            return `${addId} already seated.`
        }
    }
    // 자리 배정

    const [newN, newM, isFull] = findSafetyTable()
    // 자리가 없다
    if (isFull) {
        return `There are no more seats.`
    }
    // 자리가 있다
    else {
        // 자리 체크
        table[newN][newM] = true
        // 로그 남기기
        tableIdLog[addId] = [newN, newM]
        return `${addId} gets the seat (${newN + 1}, ${newM + 1}).`
    }
}

problems.forEach(problem => {
    const [inout, id] = problem.trim().split(/\s+/);
    if (inout === 'Out') {
        output += processOut(id) + '\n'
    }
    else if (inout === 'In') {
        output += processIn(id) + '\n'
    }
})

console.log(output.trim())




/*
아 이걸 어떻게 푸냐
좌석 개수가 적으니깐, 하나하나 전부 비교해서 풀어란 의미인 듯

좌석 전부 비교
루트는 하지않고 제곱한 것만 비교
빅인트 여부 -> 빅인트 불필요

사람이 앉을 때 마다
빈자리를 선택해서 먹는 좌석에대해서 안전 검사를 진행하고
다른 빈자리를 또 선택해서 이걸 반복...

안전도 검사 관련해서는 최적화가 안된다. 매번 안전도 순서는 바뀌니

 */
#[21년_재직자_대회_예선]_좌석_관리
#js

이 카테고리의 톡 더보기