[백준 | Java Bronze II ] (#1673) 치킨 쿠폰
문제
https://www.acmicpc.net/problem/1673
접근
강민이는 치킨 한 마리를 주문할 수 있는 치킨 쿠폰을 n장 가지고 있다. 이 치킨집에서는 치킨을 한 마리 주문할 때마다 도장을 하나씩 찍어 주는데, 도장을 k개 모으면 치킨 쿠폰 한 장으로 교환할 수 있다.
강민이가 지금 갖고 있는 치킨 쿠폰으로 치킨을 최대 몇 마리나 먹을 수 있는지 구하여라. 단, 치킨을 주문하기 위해서는 반드시 치킨 쿠폰을 갖고 있어야 한다.
예제 입력
4 3
10 3
100 5
예제 출력
5
14
124
- 쿠폰 4장을 가지고 있고, 도장 3개에 쿠폰 1장을 주는 경우
쿠폰 3장을 통해 3마리를 시키고, 쿠폰 한 장을 더 받는다.
나머지 쿠폰 두 장을 통해 두 마리를 더 시킨다.
=> 총 5마리
- 쿠폰 10장을 가지고 있고, 도장 3개에 쿠폰 1장을 주는 경우
쿠폰 3장으로 3마리를 시키고, 쿠폰 한 장을 받는다.
쿠폰 3장으로 3마리를 시키고, 쿠폰 한 장을 받는다.
쿠폰 3장으로 3마리를 시키고, 쿠폰 한 장을 받는다.
(현재 쿠폰 4장)
쿠폰 3장으로 3마리를 시키고, 쿠폰 한장을 받는다.
(현재 쿠폰 2장)
나머지 쿠폰 두 장을 통해 두 마리를 더 시킨다.
=> 총 14마리
첫번째 제출 - 실패 (런타임 에러: Null Pointer)
package week11.baek.july16.baek;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class B1673 {
public static void chicken(int n , int k){
int chicken = 0;
//쿠폰이 k장 이상일 동안 반복
while(n >= k) {
chicken += k;
n -= k - 1;
}
chicken += n;
System.out.println(chicken);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
while(st.hasMoreElements()) {
if(st.countTokens() == 0) break;
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
chicken(n, k);
st = new StringTokenizer(br.readLine());
}
}
}
st.hasMoreElements()로 while문의 조건을 걸어주면 안됐다.
String input;
while((input = br.readLine()) != null && !input.isEmpty()) {
st = new StringTokenizer(input);
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
chicken(n, k);
}
이런 식으로 input에 먼저 br.readLine()으로 받고, 그게 null이지 않을때만 실행되도록 한다.
input.isEmpty()는 입력된 게 빈 줄 일 경우가 아닐 때 실행되도록 한다.
백준으로 검사를 돌렸을 때는 아래 조건만 걸어줘도 통과됐다.
while((input = br.readLine()) != null) {
}
하지만 인텔리제이에서 입력을 복사해 실행할 때는 뒷 조건까지 붙여줘야 다음 에러가 뜨지 않았다.
인텔리제이에서 실행할 때 while((input = br.readLine()) != null) 조건만 사용할 경우 발생하는 NoSuchElementException은 빈 줄이 입력된 경우 발생한다. 백준에서는 입력이 항상 존재하는 상황에서 실행되기 때문에 문제가 발생하지 않지만, 인텔리제이에서는 사용자가 직접 입력을 제공해야 하므로 빈 줄이 입력되는 상황이 발생할 수 있다.
다음은 이러한 문제를 방지하기 위해 while((input = br.readLine()) != null && !input.isEmpty()) 조건을 사용하는 이유이다.
- 빈 줄 입력 처리: 인텔리제이에서 실행할 때 사용자가 빈 줄을 입력하면 StringTokenizer가 더 이상 토큰을 찾지 못하게 되어 NoSuchElementException이 발생한다.
- nextToken() 호출 문제: 빈 줄이 입력된 상태에서 nextToken()을 호출하면 토큰이 없기 때문에 예외가 발생한다.
최종 코드
package week11.baek.july16.baek;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class B1673 {
public static void chicken(int n , int k){
int chicken = 0;
//쿠폰이 k장 이상일 동안 반복
while(n >= k) {
chicken += k;
n -= k - 1;
}
chicken += n;
System.out.println(chicken);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
String input;
while((input = br.readLine()) != null && !input.isEmpty()) {
st = new StringTokenizer(input);
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
chicken(n, k);
}
}
}