https://www.acmicpc.net/problem/2501
Answer
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
int N = 0;
int K = 0;
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
} catch (IOException e) {
System.err.print("ERROR = " + e.getMessage());
}
System.out.println(calculateDivisor(N, K));
}
static int calculateDivisor(int N, int K) {
int result = 0;
int divisorCount = 0;
for (int i = 1; i <= N; i++) {
if (N % i == 0) {
if (++divisorCount == K) {
result = i;
break;
}
}
}
return result;
}
}
Code Review
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
...
} catch (IOException e) {
System.err.print("ERROR = " + e.getMessage());
}
`try-with-resources`로 try에 자원 객체를 받아서 try문이 끝나면 그 자원을 반환한다.
`System.in`으로 사용자로부터 입력받은 데이터를 바이트 스트림으로 받는다.
`InputStreamReader` 클래스로 바이트 스트림을 문자 기반 스트림으로 변환한다.
`BufferedReader` 클래스로 문자 스트림을 읽는다.
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
`StringTokenizer` 클래스로 입력받은 문자열 한 행을 공백 구분자로 나눈다.
`nextToken()` 메서드로 공백으로 나뉜 문자를 N, K에 대입한다.
`Integer.parseInt()` 메서드로 문자 타입을 정수 타입으로 변환한다.
System.out.println(calculateDivisor(N, K));
static int calculateDivisor(int N, int K) {
int result = 0;
int divisorCount = 0;
for (int i = 1; i <= N; i++) {
if (N % i == 0) {
if (++divisorCount == K) {
result = i;
break;
}
}
}
return result;
}
문제에서 원하는 약수에 대한 계산을 위해 `calculateDivisor()` 메서드를 생성했다.
약수를 구하기 위해 for문으로 1부터 숫자 N까지 1씩 늘려가며 로직을 반복한다.
예를 들어 N이 6이면 1부터 6까지 1씩 늘려가며 로직을 반복한다.
약수는 숫자 N을 다른 수로 나눴을 때 나머지가 0이 나오면 되므로 `N % i == 0`로 약수를 구한다.
예를 들어, N이 6이면
- 6 % 1 = 0
- 6 % 2 = 0
- 6 % 3 = 0
- 6 % 4 = 2
- 6 % 5= 1
- 6 % 6 = 0
이므로 나머지가 0인 1, 2, 3, 6이 숫자 6의 약수가 된다.
만약 `N % i == 0`식으로 약수임이 증명되면 약수 개수 `++divisorCount`를 증가시키고 K번째가 맞는지 비교한다.
예를 들어, K가 3일 때 `divisorCount`가 이 로직에 들어오기 전에 0이었다면 `++`를 만나 1을 증가시켜서 `1 == 3`은 false 이므로 이어서 for문을 진행한다.
만약 `divisorCount`가 3이 되어 `3 == 3`이 true가 되면 `result`에 현재 숫자인 3을 대입하고, 문제에서 원하는 출력이 나왔으므로 더 이상 for문이 진행되지 않도록 `break`를 호출해서 반복문을 탈출한다.
위 로직에서 대입된 `result`를 반환하거나,
만약 K번째 약수가 존재하지 않으면 `result`에 들어가는 숫자는 없을 것이므로 처음에 0으로 초기화한 그대로를 반환한다.
Result