
내가 생각했을때 문제에서 원하는부분
첫 번째 줄에 왼발잡이 선수의 수 L, 오른발 잡이 선수의 수 R, 양발잡이 선수의 수 A가 주어진다.
각 수는 0이상 100이하이다.
첫 번째 줄에 최대 잔류 인원 수를 출력한다.
내가 이 문제를 보고 생각해본 부분
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));:
System.in은 표준 입력 스트림을 의미하며, 일반적으로 키보드를 통한 입력을 나타낸다.
new InputStreamReader(System.in)은 System.in에서 들어오는 바이트 데이터를 문자 데이터로 변환해 준다.
new BufferedReader(...)는 이렇게 변환된 문자 스트림을 더 빠르고 효율적으로 읽을 수 있도록 버퍼링 기능을 추가한다.
즉, br 객체는 콘솔로부터 한 줄씩 텍스트를 읽어들일 준비가 된 상태이다.
StringTokenizer st = new StringTokenizer(br.readLine());:
br.readLine(): BufferedReader 객체 br을 사용하여 표준 입력으로부터 한 줄의 텍스트를 읽어들인다.
예를 들어, 사용자가 "1 5 2"를 입력하면 이 문자열이 반환된다.
new StringTokenizer(...): 읽어들인 문자열을 StringTokenizer 객체 st에 전달한다.
StringTokenizer는 기본적으로 공백을 구분자로 사용하여 이 문자열을 "1", "5", "2"와 같은 개별적인 문자열 조각(토큰)으로 나눌 준비를 한다.
int L = Integer.parseInt(st.nextToken());: st.nextToken()을 호출할 때마다 StringTokenizer 객체 st에서 다음 토큰(예: 첫 번째 토큰인 "1")을 문자열 형태로 가져온다.
Integer.parseInt() 메서드는 이 문자열 "1"을 실제 정수 값 1로 변환하여 왼발잡이 선수의 수를 나타내는 변수 L에 저장한다.
마찬가지로 int R = Integer.parseInt(st.nextToken());와 int A = Integer.parseInt(st.nextToken());를 통해 오른발잡이 선수 수 R과 양발잡이 선수 수 A가 정수로 변환되어 각각의 변수에 저장된다.
int result = 0;는 최종 잔류 인원수를 저장할 변수를 선언하고 0으로 초기화한다.
이어서 if-else 조건문을 통해 문제의 조건을 두 가지 주요 시나리오로 나누어 처리해준다.
if (Math.abs(L - R) <= A) (첫 번째 시나리오)
Math.abs(L - R): L과 R 사이의 절대적인 차이(예: L=1, R=5이면 차이는 4)를 계산한다.
이 값은 L과 R의 수를 같게 만들기 위해 최소한 필요한 양발잡이 선수 A의 개수를 의미한다.
이 if 조건은 양발잡이 선수 A가 L과 R의 차이를 메우기에 충분하거나, 차이를 메우고도 남는 경우를 나타낸다.
즉, A를 적절히 사용하여 L과 R의 수를 완벽하게 같게 만들 수 있다는 의미이다.
result = (L + R + A) - ((L + R + A) % 2);:
(L + R + A): 현재 팀에 있는 모든 선수의 총합이다.
최종적으로 왼발잡이와 오른발잡이 선수의 수를 같게 만들려면, 팀에 남는 선수의 총합은 항상 짝수여야 한다(예: 왼발 5명, 오른발 5명으로 총 10명).
((L + R + A) % 2): 이 연산은 (L + R + A) 값이 홀수이면 1을 반환하고, 짝수이면 0을 반환한다.
따라서, 만약 모든 선수의 총합이 홀수라면, 1명을 제외하여 짝수로 만든다(짝을 맞출 수 없는 1명은 방출된다는 의미).
만약 총합이 짝수라면, 이 값은 0이 되어 (L + R + A) 값은 그대로 유지된다.
이로써 L과 R에 균등하게 분배될 수 있는 최대 짝수 인원수가 result에 저장된다.
else (두 번째 시나리오)
이 else 블록은 Math.abs(L - R) > A인 경우를 처리한다.
즉, 양발잡이 선수 A가 L과 R의 차이를 메우기에 부족한 경우이다.
A를 모두 사용해도 L과 R의 수를 같게 만들 수 없다는 의미이다.
result = (Math.min(L, R) + A) * 2;:
Math.min(L, R): L과 R 중 더 적은 쪽의 선수 수를 반환한다.
Math.min(L, R) + A: 양발잡이 선수 A를 모두 L과 R 중 더 적은 쪽에 더하여 그쪽의 선수 수를 늘린다. ㄴ
하지만 A가 부족하기 때문에, 이 값은 여전히 다른 쪽 선수 수보다 적게 된다.
* 2: L과 R의 수를 같게 만들어야 하므로, 최종적으로 팀에 남는 선수는 (더 적은 쪽 선수 수 + A)를 기준으로 2배가 된다.
예를 들어, L이 3명이고 R이 5명일 때 A가 1명이라면, L에 A를 더해 L은 4명이 된다.
이제 L은 4명, R은 5명이다.
이 경우 4명씩 짝을 이뤄 총 8명만 남길 수 있다.
즉, (Math.min(L, R) + A)의 2배가 된다.
코드로 구현
package baekjoon.baekjoon_29;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
// 백준 15734번 문제
public class Main1069 {
public static void main(String[] args) throws IOException {
// 1. 입력 처리 부분
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int L = Integer.parseInt(st.nextToken()); // 왼발잡이 선수 수
int R = Integer.parseInt(st.nextToken()); // 오른발 잡이 선수 수
int A = Integer.parseInt(st.nextToken()); // 양발잡이 선수 수
// 2. 문제 해결 핵심 로직
int result = 0; // 최종 잔류 인원 수를 저장할 변수
// L과 R의 차이를 A로 메울 수 있는지 여부에 따라 두 가지 경우로 나뉩니다.
if(Math.abs(L - R) <= A) {
// 경우 1: A가 L과 R의 차이를 메우기에 충분하거나 남는 경우
// Math.abs(L - R)는 L과 R의 절대적인 차이를 계산합니다.
// 이 조건은 양발잡이 선수 A를 사용하여 L과 R의 수를 같게 만들 수 있다는 의미입니다.
// (L + R + A)는 모든 선수의 총합입니다.
// L과 R의 수를 같게 만들려면, 남은 선수들을 짝수 명으로 유지해야 합니다.
// 예를 들어, L=5, R=5, A=10 이라면 총 20명입니다. (5+5+10)
// A를 사용하여 L,R이 같아진 후 남은 A는 (A - Math.abs(L-R)) 명입니다.
// 이 남은 A는 L과 R에 똑같이 분배되어야 합니다. (예: L에 1명, R에 1명)
// 따라서 전체 인원 (L + R + A)가 홀수이면 1명을 버려야 합니다.
// (L + R + A) % 2는 (L + R + A)가 홀수이면 1, 짝수이면 0을 반환합니다.
// 이 값을 전체 인원에서 빼주면, 항상 짝수 명의 선수만 남게 됩니다.
result = (L + R + A) - ((L + R + A) % 2);
} else {
// 경우 2: A가 L과 R의 차이를 메우기에 부족한 경우
// Math.abs(L - R) > A는 양발잡이 선수 A만으로는 L과 R의 차이를 완전히 메울 수 없다는 의미입니다.
// 이 경우, A를 모두 사용하여 L과 R 중 더 적은 쪽의 선수 수를 늘립니다.
// Math.min(L, R)은 L과 R 중 더 작은 값을 반환합니다.
// 이 작은 값에 A를 모두 더해도, 여전히 다른 쪽 선수 수보다 적게 됩니다.
// (예: L=1, R=5, A=2. Math.min(1, 5)는 1. 1 + 2 = 3. 여전히 R=5보다 작음)
// 최종적으로 팀에 남는 선수의 수는, A를 더한 후의 더 적은 쪽 선수 수의 두 배가 됩니다.
// 왜냐하면, L과 R의 수가 같아야 하므로, 더 적은 쪽에 맞춰서 선수를 남겨야 하기 때문입니다.
result = (Math.min(L, R) + A) * 2;
}
// 3. 결과 출력 부분
System.out.println(result);
}
}
코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.