문제
미국으로 유학간 동혁이는 세탁소를 운영하고 있다. 동혁이는 최근에 아르바이트로 고등학생 리암을 채용했다.
동혁이는 리암에게 실망했다.
리암은 거스름돈을 주는 것을 자꾸 실수한다.
심지어 $0.5달러를 줘야하는 경우에 거스름돈으로 $5달러를 주는것이다!
어쩔수 없이 뛰어난 코딩 실력을 발휘해 리암을 도와주는 프로그램을 작성하려고 하지만, 디아블로를 하느라 코딩할 시간이 없어서 이 문제를 읽고 있는 여러분이 대신 해주어야 한다.
거스름돈의 액수가 주어지면 리암이 줘야할 쿼터(Quarter, $0.25)의 개수, 다임(Dime, $0.10)의 개수, 니켈(Nickel, $0.05)의 개수, 페니(Penny, $0.01)의 개수를 구하는 프로그램을 작성하시오. 거스름돈은 항상 $5.00 이하이고, 손님이 받는 동전의 개수를 최소로 하려고 한다. 예를 들어, $1.24를 거슬러 주어야 한다면, 손님은 4쿼터, 2다임, 0니켈, 4페니를 받게 된다.
입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 거스름돈 C를 나타내는 정수 하나로 이루어져 있다. C의 단위는 센트이다. (1달러 = 100센트) (1<=C<=500)
출력
각 테스트케이스에 대해 필요한 쿼터의 개수, 다임의 개수, 니켈의 개수, 페니의 개수를 공백으로 구분하여 출력한다.
예제 입력 1
3
124
25
194
예제 출력 1
4 2 0 4
1 0 0 0
7 1 1 4
https://www.acmicpc.net/problem/2720
금액을 최소 개수의 동전으로 나누어 주는 문제. 동전의 종류는 25센트(쿼터), 10센트(다임), 5센트(니켈), 1센트(페니)이며, 이 동전들을 활용해서 거스름돈을 거슬러 주어야 함.
문제 해결 전략
1. 큰 단위의 동전부터 사용: 거스름돈을 최소 개수의 동전으로 거슬러 주어야 하기 때문에, 큰 단위의 동전으로 거슬러 주어야 하기 때문에, 큰 단위의 동전(쿼터)부터 차례대로 사용할 것
- 먼저 쿼터(25센트)로 나눌 수 있는 최대 개수를 구하고, 남은 금액을 처리
- 그다음 다임(10센트), 니켈(5센트), 페니(1센트) 순으로 반복
2. 계산 순서
- 주어진 거스름돈을 25로 나눈 몫이 쿼터의 개수가 됨. 몫을 구한 후에는 나머지 금액이 남으므로, 이 나머지 금액에 대해 같은 방법으로 다임, 니켈, 페니 계산
- 예를 들어, 124센트를 처리하는 경우:
- 124 / 25 = 4 (쿼터 4개), 나머지 124 % 25 = 24
- 24 / 10 = 2 (다임 2개), 나머지 24 % 10 = 4
- 4 / 5 = 0 (니켈 0개), 나머지 4 % 5 = 4
- 4 / 1 = 4 (페니 4개)
3. 입력과 출력:
- 입력으로는 거스름돈의 센트 단위가 주어지며, 각 테스트 케이스마다 위의 과정을 반복하여 각 동전의 개수 출력
- 출력은 쿼터, 다임, 니켈, 페니의 개수를 공백으로 구분하여 출력
package Algorythm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main2 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
StringBuilder result = new StringBuilder();
// 각 테스트 케이스 처리
for (int i = 0; i < T; i++) {
// 거스름 돈 입력
int cents = Integer.parseInt(br.readLine());
int quaters = cents / 25; // 쿼터의 개수
cents %= 25; // 남은 센트 계산
int dimes = cents / 10; // 다임의 개수
cents %= 10; // 남은 다임 계산
int nickels = cents / 5; // 니켈의 개수
cents %= 5; // 남은 니켈의 개수
int pennies = cents; // 페니의 개수(1센트 동전)
result.append(quaters).append(" ")
.append(dimes).append(" ")
.append(nickels).append(" ")
.append(pennies).append("\n");
}
System.out.println(result.toString());
}
}
그리디인 이유
그리디 알고리즘: 매 순간마다 최선의 선택을 해서 최종적인 해결책을 찾는 알고리즘
설명
1. 최선의 선택: 매번 남은 거스름돈을 가장 큰 단위의 동전부터 가능한 최대 개수만큼 사용하여 처리
- 예를 들어, 124 센트를 처리할 때, 가장 먼저 쿼터(25센트)를 사용할 수 있는 최대 개수를 계산. 이 과정에서 쿼터 4개를 선택하고, 나머지를 처리
2. 부분 문제의 최적 해결: 큰 단위의 동전을 선택한 후에 남은 거스름돈에 대해 같은 방식으로 반복적으로 처리. 각 단계에서 거스름돈을 최소화하기 위한 최선의 선택(가장 큰 단위의 동전 사용)이 이루어짐
3. 전체 문제 해결: 각 단계에서 부분 문제를 최적으로 해결하는 방식이 전체 문제의 최적 해결로 이어짐. 즉, 쿼터, 다임, 니켈, 페니 순으로 선택하는 방식이 결국 최적의 동전 개수를 보장
그리디 알고리즘의 특성
- 지역 최적해(Local Optimal)를 통해 전역 최적해(Global Optimal)를 얻을 수 있는 문제에서는 그리디 알고리즘이 효과적
- 이 문제에서는 동전의 단위가 25, 10, 5, 1 센트로 설정되어 있어, 항상 큰 단위의 동전을 우선적으로 사용하는 것이 동전의 개수를 최소화하는 최적의 방법이 됨
결론
이 문제는 그리디 알고리즘의 대표적인 예로, 각 단계에서 남은 거스름돈에 대해 가장 큰 단위의 동전을 최대한 사용하는 방식으로 최소 동전 개수를 보장할 수 있음
'알고리즘 > 백준' 카테고리의 다른 글
| 백준 5585 거스름돈 (0) | 2024.10.15 |
|---|---|
| [백준] 10162 전자레인지 (1) | 2024.10.15 |
| 백준 9375 패션왕 신해빈 (0) | 2024.08.12 |
| 백준 3190 뱀 (0) | 2024.07.27 |
| 백준 17298 오큰수 (3) | 2024.07.24 |