관리 메뉴

πŸ–₯ dev-ruby

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] 배달 - Lv.2 javascript <Summer/Winter ~2018> λ³Έλ¬Έ

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] 배달 - Lv.2 javascript <Summer/Winter ~2018>

ruby_s 2021. 11. 25. 21:13
728x90
λ°˜μ‘ν˜•
SMALL

문제 μ„€λͺ…

N개의 λ§ˆμ„λ‘œ 이루어진 λ‚˜λΌκ°€ μžˆμŠ΅λ‹ˆλ‹€. 이 λ‚˜λΌμ˜ 각 λ§ˆμ„μ—λŠ” 1λΆ€ν„° NκΉŒμ§€μ˜ λ²ˆν˜Έκ°€ 각각 ν•˜λ‚˜μ”© λΆ€μ—¬λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 각 λ§ˆμ„μ€ μ–‘λ°©ν–₯으둜 톡행할 수 μžˆλŠ” λ„λ‘œλ‘œ μ—°κ²°λ˜μ–΄ μžˆλŠ”λ°, μ„œλ‘œ λ‹€λ₯Έ λ§ˆμ„ 간에 이동할 λ•ŒλŠ” 이 λ„λ‘œλ₯Ό μ§€λ‚˜μ•Ό ν•©λ‹ˆλ‹€. λ„λ‘œλ₯Ό 지날 λ•Œ κ±Έλ¦¬λŠ” μ‹œκ°„μ€ λ„λ‘œλ³„λ‘œ λ‹€λ¦…λ‹ˆλ‹€. ν˜„μž¬ 1번 λ§ˆμ„μ— μžˆλŠ” μŒμ‹μ μ—μ„œ 각 λ§ˆμ„λ‘œ μŒμ‹ 배달을 ν•˜λ €κ³  ν•©λ‹ˆλ‹€. 각 λ§ˆμ„λ‘œλΆ€ν„° μŒμ‹ 주문을 λ°›μœΌλ €κ³  ν•˜λŠ”λ°, N개의 λ§ˆμ„ μ€‘μ—μ„œ K μ‹œκ°„ μ΄ν•˜λ‘œ 배달이 κ°€λŠ₯ν•œ λ§ˆμ„μ—μ„œλ§Œ 주문을 λ°›μœΌλ €κ³  ν•©λ‹ˆλ‹€. λ‹€μŒμ€ N = 5, K = 3인 경우의 μ˜ˆμ‹œμž…λ‹ˆλ‹€.

μœ„ κ·Έλ¦Όμ—μ„œ 1번 λ§ˆμ„μ— μžˆλŠ” μŒμ‹μ μ€ [1, 2, 4, 5] 번 λ§ˆμ„κΉŒμ§€λŠ” 3 μ΄ν•˜μ˜ μ‹œκ°„μ— 배달할 수 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 3번 λ§ˆμ„κΉŒμ§€λŠ” 3μ‹œκ°„ μ΄λ‚΄λ‘œ 배달할 수 μžˆλŠ” κ²½λ‘œκ°€ μ—†μœΌλ―€λ‘œ 3번 λ§ˆμ„μ—μ„œλŠ” 주문을 받지 μ•ŠμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ 1번 λ§ˆμ„μ— μžˆλŠ” μŒμ‹μ μ΄ 배달 주문을 받을 수 μžˆλŠ” λ§ˆμ„μ€ 4κ°œκ°€ λ©λ‹ˆλ‹€.
λ§ˆμ„μ˜ 개수 N, 각 λ§ˆμ„μ„ μ—°κ²°ν•˜λŠ” λ„λ‘œμ˜ 정보 road, μŒμ‹ 배달이 κ°€λŠ₯ν•œ μ‹œκ°„ Kκ°€ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§ˆ λ•Œ, μŒμ‹ 주문을 받을 수 μžˆλŠ” λ§ˆμ„μ˜ 개수λ₯Ό return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄μ£Όμ„Έμš”.

μ œν•œμ‚¬ν•­

  • λ§ˆμ„μ˜ 개수 N은 1 이상 50 μ΄ν•˜μ˜ μžμ—°μˆ˜μž…λ‹ˆλ‹€.
  • road의 길이(λ„λ‘œ μ •λ³΄μ˜ 개수)λŠ” 1 이상 2,000 μ΄ν•˜μž…λ‹ˆλ‹€.
  • road의 각 μ›μ†ŒλŠ” λ§ˆμ„μ„ μ—°κ²°ν•˜κ³  μžˆλŠ” 각 λ„λ‘œμ˜ 정보λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • roadλŠ” 길이가 3인 배열이며, μˆœμ„œλŒ€λ‘œ (a, b, c)λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
    • a, b(1 ≤ a, b ≤ N, a != b)λŠ” λ„λ‘œκ°€ μ—°κ²°ν•˜λŠ” 두 λ§ˆμ„μ˜ 번호이며, c(1 ≤ c ≤ 10,000, cλŠ” μžμ—°μˆ˜)λŠ” λ„λ‘œλ₯Ό μ§€λ‚˜λŠ”λ° κ±Έλ¦¬λŠ” μ‹œκ°„μž…λ‹ˆλ‹€.
    • 두 λ§ˆμ„ a, bλ₯Ό μ—°κ²°ν•˜λŠ” λ„λ‘œλŠ” μ—¬λŸ¬ κ°œκ°€ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
    • ν•œ λ„λ‘œμ˜ 정보가 μ—¬λŸ¬ 번 μ€‘λ³΅ν•΄μ„œ 주어지지 μ•ŠμŠ΅λ‹ˆλ‹€.
  • KλŠ” μŒμ‹ 배달이 κ°€λŠ₯ν•œ μ‹œκ°„μ„ λ‚˜νƒ€λ‚΄λ©°, 1 이상 500,000 μ΄ν•˜μž…λ‹ˆλ‹€.
  • μž„μ˜μ˜ 두 λ§ˆμ„κ°„μ— 항상 이동 κ°€λŠ₯ν•œ κ²½λ‘œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.
  • 1번 λ§ˆμ„μ— μžˆλŠ” μŒμ‹μ μ΄ K μ΄ν•˜μ˜ μ‹œκ°„μ— 배달이 κ°€λŠ₯ν•œ λ§ˆμ„μ˜ 개수λ₯Ό return ν•˜λ©΄ λ©λ‹ˆλ‹€.

μž…μΆœλ ₯ 예

 

N road K result
5 [[1,2,1],[2,3,3],[5,2,2],[1,4,2],[5,3,1],[5,4,2]] 3 4
6 [[1,2,1],[1,3,2],[2,3,2],[3,4,3],[3,5,2],[3,5,3],[5,6,1]] 4 4

μž…μΆœλ ₯ 예 μ„€λͺ…

μž…μΆœλ ₯ 예 #

1문제의 μ˜ˆμ‹œμ™€ κ°™μŠ΅λ‹ˆλ‹€.

μž…μΆœλ ₯ 예 #2

주어진 λ§ˆμ„κ³Ό λ„λ‘œμ˜ λͺ¨μ–‘은 μ•„λž˜ κ·Έλ¦Όκ³Ό κ°™μŠ΅λ‹ˆλ‹€.


1번 λ§ˆμ„μ—μ„œ 배달에 4μ‹œκ°„ μ΄ν•˜κ°€ κ±Έλ¦¬λŠ” λ§ˆμ„μ€ [1, 2, 3, 5] 4κ°œμ΄λ―€λ‘œ 4λ₯Ό return ν•©λ‹ˆλ‹€.

 

 

λ‚΄κ°€ ν‘Ό 풀이

: μ„ ν˜•νƒμƒ‰ 방법

let n = 0;
let distance = [];  // μ‹œμž‘ μœ„μΉ˜λ‘œλΆ€ν„° 각 λ§ˆμ„κΉŒμ§€ μ΅œμ†ŒκΈΈμ΄
let visited = [];   // λ°©λ¬Έν•œ λ§ˆμ„
let graph = [];

function getSmallIdx(){
    let min = Infinity;
    let idx = 0;
    for(let i=0; i< n; i++){
        if(distance[i] < min && !visited[i]){ // λ°©λ¬Έν•˜μ§€ μ•ŠλŠ” λ§ˆμ„ μ€‘μ—μ„œ
            min = distance[i];               // κ°€μž₯ μž‘μ€ 길이λ₯Ό κ°–λŠ” λ§ˆμ„μ˜ 인덱슀 리턴
            idx = i;
        }
    }
    return idx;
}

function dijkstra(start){
    for(let i=0; i<n; i++)
        distance[i] = graph[start][i];  // μ‹œμž‘ μœ„μΉ˜μ—μ„œ 각 λ§ˆμ„κΉŒμ§€ 초기 길이 
    visited[start] = true;
    for(let i=0; i<n; i++){
        const curr = getSmallIdx(); // μ‹œμž‘ μœ„μΉ˜λ‘œλΆ€ν„° λ°©λ¬Έν•˜μ§€ μ•Šμ€ λ§ˆμ„ 쀑 μž‘μ€ 길이λ₯Ό κ°€μ§€λŠ” λ§ˆμ„
        visited[curr] = true;
        for(let j=0; j<n; j++){
            if(!visited[j] && distance[curr] + graph[curr][j] < distance[j]){    // λ°©λ¬Έ ν•˜μ§€ μ•Šμ€ λ§ˆμ„μ΄κ³ , κΈ°μ‘΄ 길이 보닀 currλ§ˆμ„μ„ κ±°μ³κ°€λŠ” 게 더 짧을 경우
                distance[j] = distance[curr] + graph[curr][j];                  // μ—…λ°μ΄νŠΈ
            }
        }
    }
}

function solution(N, road, K) {
    n = N;
    graph = Array.from(Array(n), () => new Array(n).fill(0)).map((x, i)=>x.map((y, j)=>{if(i === j) return 0; else return Infinity;})); // μžμ‹ μ˜ 경둜의 κΈΈμ΄λŠ” 0으둜 λ‚˜λ¨Έμ§€λŠ” λ¬΄ν•œλŒ€λ‘œ
    road.forEach((pair)=>{
        if(graph[pair[0]-1][pair[1]-1] > pair[2])   // 더 μž‘μ€ 경둜일 경우
            graph[pair[0]-1][pair[1]-1] = pair[2];  // μ—…λ°μ΄νŠΈ
        if(graph[pair[1]-1][pair[0]-1] > pair[2])
            graph[pair[1]-1][pair[0]-1] = pair[2];
        });
    dijkstra(0);    // μ‹œμž‘μœ„μΉ˜ 0μ—μ„œ λ‹€μ΅μŠ€νŠΈλΌ μ‹œμž‘
    return distance.reduce((acc, curr)=>acc+(curr <= K), 0);    // Kμ‹œκ°„ μ΄ν•˜ 개수 리턴
}

 

: μš°μ„ μˆœμœ„ 큐 방법

function solution(N, road, K) {
    const pq = [];
    const dist = Array(N).fill(Infinity);
    const graph = Array.from(Array(N), () => new Array(N).fill(0)).map((x, i)=>x.map((y, j)=>{if(i === j) return 0; else return Infinity;}));
    
    road.forEach(([a, b, w]) => {
        if(graph[a-1][b-1] > w) graph[a-1][b-1] = w;
        if(graph[b-1][a-1] > w) graph[b-1][a-1] = w;
    });
    
    dist[0] = 0;
    pq.push([0, 0]);
    while(pq.length > 0){
        const [node, weight] = pq.pop();
        if(dist[node] < weight) continue;

        for(let i=0; i<N; i++){
            const nextWeight = graph[node][i];
            if(dist[i] > weight + nextWeight){
                dist[i] = weight + nextWeight;
                pq.push([i, dist[i]]);
            }
        }
    }
    return dist.filter((v)=> v<=K).length;
}

λ‹€λ“€ λ³΄λ‹ˆκΉŒ object둜 adjλ³€μˆ˜μ— λ„£μ–΄μ£Όλ˜λ°,, κ·Έλ ‡κ²Œ ν•˜λŠ”κ²Œ μš°μ„ μˆœμœ„ 큐의 μ˜λ„λœ 방식인가 잘 λͺ¨λ₯΄κ² λ‹Ή ..
λ‚œ κ·Έλƒ₯ 2차원 λ°°μ—΄λ‘œ κ΅¬ν˜„ν–ˆλŠ”λ°, μ‹€ν–‰ μ‹œκ°„ μΈ‘λ©΄μ—μ„œ 이게 더 μ§§μ•˜λ‹€.. objectκ°€ μ’€ λŠλ¦°κ°€?

728x90
λ°˜μ‘ν˜•
LIST