Day Of Mourning의 기타리스트 강토가 사용하는 기타에서 N개의 줄이 끊어졌다. 따라서 새로운 줄을 사거나 교체해야 한다. 강토는 되도록이면 돈을 적게 쓰려고 한다. 6줄 패키지를 살 수도 있고, 1개 또는 그 이상의 줄을 낱개로 살 수도 있다.
끊어진 기타줄의 개수 N과 기타줄 브랜드 M개가 주어지고, 각각의 브랜드에서 파는 기타줄 6개가 들어있는 패키지의 가격, 낱개로 살 때의 가격이 주어질 때, 적어도 N개를 사기 위해 필요한 돈의 수를 최소로 하는 프로그램을 작성하시오.
입력:
첫째 줄에 N과 M이 주어진다. N은 100보다 작거나 같은 자연수이고, M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 M개의 줄에는 각 브랜드의 패키지 가격과 낱개의 가격이 공백으로 구분하여 주어진다. 가격은 0보다 크거나 같고, 1,000보다 작거나 같은 정수이다.
public class GuitarString {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
// 끊어진 기타줄 수 N과 브랜드 M개 입력 받기
int BrokenString = scanner.nextInt();
int BrandNum = scanner.nextInt();
// 브랜드 수만큼의 칸을 가진, 패키지 가격과 낱개 가격에 대한 배열 생성
int[] packagePrice = new int[BrandNum];
int[] unitPrice = new int[BrandNum];
// i가 브랜드 수 즉 주어진 옵션만큼을 다 순회하는 반복문 사용
for(int i = 0; i < BrandNum; i++) {
// 들어오는 값을 순차적으로 패키지 가격 배열과 낱개 가격 배열에 추가
packagePrice[i] = scanner.nextInt();
unitPrice[i] = scanner.nextInt();
}
// 가장 싼 가격이 앞으로 오게 배열 오름차순 정렬
Arrays.sort(packagePrice);
Arrays.sort(unitPrice);
// 답안 초기화
int res = 0;
//Math.min() 함수를 이용해
// 1) 가장 싼 패키지 가격 vs. 가장 싼 낱개 가격
// 2) 1)에서 더 적은 가격 vs. 패키지+낱개 혼합 구매 가격
res = Math.min(((BrokenString/6)+1)*packagePrice[0], BrokenString*unitPrice[0]);
res = Math.min(res, (BrokenString%6)*unitPrice[0] + (BrokenString/6)*packagePrice[0]);
// 답안 출력
System.out.println(res);
}
}
주어지는 N과 M에 대한 모든 가격 조합을 구해서 이중 제일 작은 수를 반환하는 방식을 떠올렸었다. 그러나 코드가 매우 지저분할 것 같았고 이보다 단순하게 구현할 방법이 분명 있을 것 같았다.
결국 쓸 값은 가장 싼 가격이기 때문에, N과 M을 각기 다른 배열에 넣어서 정렬만 하면 되겠다고 떠올렸다. 이후 주어진 옵션이 총 3가지(패키지only, 낱개only, 혼합구매)라고 이해했고, Math.min() 메서드로 가장 싼 가격을 찾았다.
쉬운 문제인데 애초의 접근대로 구현했다면 시간을 많이 낭비했을 거다...🥹