2026. 4. 29. 09:45ㆍProgrammers
[C++] 콜라 문제 — 프로그래머스 풀이
C++ / 시뮬레이션 / 반복문
문제 설명
빈 병 a개를 가져다주면 콜라 b병을 주는 마트가 있다
처음 가지고 있는 빈 병 n개로 받을 수 있는 콜라의 총 개수를 구하는 문제다
단, 보유 중인 빈 병이 a개 미만이면 더 이상 콜라를 받을 수 없다
예시
a = 2, b = 1, n = 20인 경우
20병 → 10병 받음 → 다시 10병 가져감
10병 → 5병 받음 → 다시 5병 가져감
5병 → 4병 가져가서 2병 받음 (남은 빈 병 1)
2 + 1 = 3병 → 2병 가져가서 1병 받음 (남은 빈 병 1)
1 + 1 = 2병 → 1병 받음
총 10 + 5 + 2 + 1 + 1 = 19병
문제 해석
핵심은 반복적으로 빈 병을 교환하는 시뮬레이션이다
한 번의 교환에서 신경 써야 할 값이 두 개 있다
- 새로 받는 콜라 개수: (n / a) * b
- 교환하지 못하고 남은 빈 병: n % a
다음 라운드의 빈 병은 새로 받은 콜라 + 남은 빈 병이 된다
이 과정을 빈 병이 a 미만이 될 때까지 반복하면서 받은 콜라를 누적하면 된다
문제 풀이
#include <string>
#include <vector>
using namespace std;
int solution(int a, int b, int n) {
int answer = 0;
int m = 0; // 새로 받는 콜라
while(n >= a)
{
m = (n / a) * b; // 받는 콜라 개수
int k = n % a; // 남은 빈 병
answer += m;
n = m + k; // 다음 라운드 빈 병
}
return answer;
}
핵심 포인트
1. while 조건은 n >= a
빈 병이 정확히 a개일 때도 교환이 가능하므로 >=을 써야 한다
>로 쓰면 마지막 한 번의 교환을 놓치게 된다
처음에 n>a로 사용해서 오류가 났어서 n>=a로 수정해서 작성했다.
while(n >= a) // a개도 교환 가능
while(n > a) // a개일 때 교환 못함
2. 다음 라운드 빈 병은 "받은 콜라 + 남은 빈 병"
흔히 헷갈리는 부분이다. 다음 라운드에 가져갈 빈 병의 개수를 계산해야 한다
n = m + k; // 받은 콜라(m) + 남은 빈 병(k)
받은 콜라를 다 마시면 그게 새 빈 병이 되고, 교환하지 못한 빈 병은 그대로 들고 가야 하므로 둘을 더해야 한다
3. n / a와 n % a의 활용
정수 나눗셈의 몫과 나머지를 활용하면 한 번의 교환을 깔끔하게 처리할 수 있다
- n / a → 몇 번 교환할 수 있는지 (자동 버림)
- n % a → 교환하지 못하고 남는 빈 병
트러블슈팅
1. 무한 루프
처음에 작성한 코드는 n 값을 갱신하지 않아 while 조건이 영원히 참인 상태였다
// 잘못된 코드
while(n > a)
{
m = (n / a) * b;
answer += m;
// n이 그대로 → 무한 루프
}
각 라운드마다 n을 다음 라운드의 빈 병 개수로 갱신해줘야 한다는 걸 놓쳤다
시뮬레이션 문제에서는 상태 변수가 매 라운드 갱신되는지 항상 체크해야 한다
2. 다음 라운드 빈 병 계산 실수
처음에는 다음 라운드 n을 이렇게 계산했다
n = n / a + k;
a = 2, b = 1일 때는 n / a == m이라 우연히 정답이 나왔지만, a = 3, b = 2처럼 b가 다른 경우엔 틀린다
교환 횟수(n / a) 와 받은 콜라 개수(m) 는 다른 값이다
다음 라운드에 들고 가는 빈 병은 받은 콜라 개수여야 하므로 m + k가 맞다
3. while 조건 비교 연산자
while(n > a)로 작성해서 마지막 라운드를 놓쳤다
a = 2, n = 2인 경우를 직접 손으로 따라가 보면 한 번 더 교환할 수 있어야 한다는 걸 알 수 있다
경계값을 직접 대입해보는 습관이 중요하다
'Programmers' 카테고리의 다른 글
| < 프로그래머스 C++ > 2016년 (0) | 2026.05.01 |
|---|---|
| < 프로그래머스 C++ > 명예의 전당(1) (0) | 2026.04.30 |
| < 프로그래머스 C++ > 푸드 파이트 대회 (0) | 2026.04.28 |
| < 프로그래머스 C++ > 가장 가까운 같은 글자 (0) | 2026.04.27 |
| < 프로그래머스 C++ > 두 개 뽑아서 더하기 (0) | 2026.04.24 |