Post

BOJ_2258_정육점 (Java)

BOJ_2258_정육점 (Java)

[Gold III] 정육점 - 2258

문제 링크

성능 요약

메모리: 43920 KB, 시간: 492 ms

분류

그리디 알고리즘, 정렬

제출 일자

2025년 5월 6일 15:16:41

문제 설명

은혜는 정육점에서 고기를 사려고 한다. 보통 정육점에서는 자신이 원하는 양을 이야기하면 그 양만큼의 고기를 팔지만, 은혜가 방문한 정육점에서는 세일 행사를 하고 있었기 때문에 N 덩어리의 고기를 이미 잘라놓고 판매하고 있었다.

각각의 덩어리들은 이미 정해져 있는 무게와 가격이 있는데, 어떤 덩어리를 샀을 때에는 그 덩어리보다 싼 고기들은 얼마든지 덤으로 얻을 수 있다(추가 비용의 지불 없이). 또한 각각의 고기들은 부위가 다를 수 있기 때문에 비용과 무게와의 관계가 서로 비례하는 관계가 아닐 수도 있다. 은혜는 이러한 점을 고려하지 않고, 어느 부위든지 자신이 원하는 양만 구매하면 되는 것으로 가정한다. 또한 만약 가격이 더 싸다면 은혜가 필요한 양보다 더 많은 고기를 살 수도 있다.

각 덩어리에 대한 정보가 주어졌을 때, 은혜가 원하는 양의 고기를 구매하기 위해 필요한 최소 비용을 계산하는 프로그램을 작성하시오.

입력

첫째 줄에 두 정수 N(1 ≤ N ≤ 100,000), M(1 ≤ M ≤ 2,147,483,647)이 주어진다. N은 덩어리의 개수를 의미하고, M은 은혜가 필요한 고기의 양이다. 다음 N개의 줄에는 각 고기 덩어리의 무게와 가격을 나타내는 음 아닌 두 정수가 주어진다. 무게의 총 합과 가격의 총 합은 각각 2,147,483,647을 넘지 않는다.

출력

첫째 줄에 답을 출력한다. 불가능한 경우에는 -1을 출력한다.

문제 풀이

가격 기준으로 오름차순한다. 가격이 같으면 더해야하고 가격이 높아지면 그 가격으로도 아래가격 고기 다 살 수 있다. 그리고 고기 무게는 내림차순으로 무거운것부터 같은 가격으로 사면 좋으니 그렇게 정렬기준을 세운다.

코드

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
 * Author: nowalex322, Kim HyeonJae
 */

import java.io.*;
import java.util.*;

public class Main {
    class Meat implements Comparable<Meat>{
        int w, p;
        public Meat(int w, int p) {
            this.w = w;
            this.p = p;
        }

        @Override
        public int compareTo(Meat o) {
            if(this.p == o.p) return o.w - this.w;
            return this.p - o.p;
        }
    }
    static BufferedReader br;
    static BufferedWriter bw;
    static StringTokenizer st;
    static int N, M;
    static long res = Long.MAX_VALUE;
    static Meat[] meat;
    public static void main(String[] args) throws Exception {
        new Main().solution();
    }

    public void solution() throws Exception {
        br = new BufferedReader(new InputStreamReader(System.in));
//        br = new BufferedReader(new InputStreamReader(new FileInputStream("src/main/java/BOJ_2258_정육점/input.txt")));
        bw = new BufferedWriter(new OutputStreamWriter(System.out));

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        meat = new Meat[N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            meat[i] = new Meat(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));
        }

        Arrays.sort(meat);

        int prevP=0;
        int Wsum=0;
        int currP=0;
        for(Meat m : meat) {
            if(m.p > prevP) {
                prevP = m.p;
                currP = m.p;
            }
            else if(m.p == prevP) currP+=m.p;

            Wsum += m.w;

            if(Wsum >= M) res = Math.min(res, currP);
        }

        if (Wsum < M || res > 2_147_483_647) res = -1;

        System.out.println(res);

        br.close();
    }
}
This post is licensed under CC BY 4.0 by the author.