
내가 생각했을때 문제에서 원하는부분
첫 번째 줄에는 수식의 개수 T가 주어진다. (1 ≤ T ≤ 1000)
두 번째 줄부터 T개의 수식이 한 줄에 하나씩 주어진다.
하나의 수식은 a개의 느낌표, 정수 n, b개의 느낌표가 공백 없이 순서대로 합쳐진 형태이다. (0 ≤ a,b ≤ 30; 0 ≤ n ≤ 1)
각 수식을 계산한 결과를 한 줄에 하나씩 출력한다.
내가 이 문제를 보고 생각해본 부분
입력 처리 및 초기 설정:
BufferedReader와 BufferedWriter: 많은 양의 입출력을 처리할 때 효율성을 위해 사용한다.
T개의 테스트 케이스를 받아야 한다.
int T = Integer.parseInt(br.readLine());: 첫 번째 줄에서 테스트 케이스의 개수 T를 읽어온다.
int a = 0; int b = 0; int n = -1;: 각 수식마다 a(앞 느낌표 개수), b(뒤 느낌표 개수), n(숫자)를 저장할 변수를 초기화한다.
n은 0 또는 1이므로 -1로 초기화하여 아직 값을 찾지 못했음을 나타낸다.
수식 파싱(Parsing Expression):
for(int j = 0; j < expression.length(); j++): 수식 문자열을 순회하면서 숫자 n의 위치를 찾는다.
if(c == '0' || c == '1'): 문자가 0 또는 1인지 확인한다.
n = Character.getNumericValue(c);: 찾은 숫자를 n에 저장한다.
nIndex = j; break;: 숫자의 인덱스를 nIndex에 저장하고 반복을 종료한다.
a = nIndex;: 숫자가 있는 인덱스가 바로 n 앞에 붙은 !의 개수 a가 된다. (문자열 시작부터 n까지의 길이)
b = expression.length() - (nIndex + 1);: 전체 문자열 길이에서 n까지의 길이 (nIndex + 1)를 빼면 n 뒤에 붙은 !의 개수 b를 얻을 수 있다.
수식 계산 로직:
if (b > 0):
이 조건은 수식에 n! 형태가 포함되어 있음을 의미한다.
문제 규칙에 따라 0!이든 1!이든 n!의 결과는 항상 1이다.
따라서, n과 b는 더 이상 결과에 영향을 주지 않고, 현재 값은 1이 된다.
이제 남은 a개의 논리 반전 (!) 연산만 1에 적용하면 된다.
if (a % 2 == 0): a가 짝수이면 ! 연산이 짝수 번 반복되므로 1은 그대로 1이다.
else: a가 홀수이면 ! 연산이 홀수 번 반복되므로 1은 0으로 반전된다.
계산된 result를 bw.write(result + "\n");를 통해 출력한다.
else (b == 0):
이 조건은 수식에 n! 형태가 없음을 의미합니다. 즉, n 뒤에는 !가 없다.
n 값은 그대로 유지되며, a개의 논리 반전 (!) 연산만 n에 적용된다.
이는 n과 (a % 2)를 XOR(배타적 논리합) 연산하는 것과 동일한다.
n=0, a%2=0 (a 짝수) -> 0 ^ 0 = 0
n=0, a%2=1 (a 홀수) -> 0 ^ 1 = 1
n=1, a%2=0 (a 짝수) -> 1 ^ 0 = 1
n=1, a%2=1 (a 홀수) -> 1 ^ 1 = 0
이렇게 계산된 result를 출력한다.
출력 및 자원 해제:
bw.flush();: 버퍼에 남아있는 모든 내용을 출력 스트림으로 보낸다.
br.close(); bw.close();: 사용이 끝난 스트림 자원들을 해제한다.
코드로 구현
package baekjoon.baekjoon_31;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
// 백준 31458번 문제
public class Main1214 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int T = Integer.parseInt(br.readLine());
for(int i = 0; i < T; i++) {
String expression = br.readLine();
int a = 0; // n 앞의 느낌표 개수
int b = 0; // n 뒤의 느낌표 개수
int n = -1; // 숫자 n
// 수식 파싱
int nIndex = -1;
for(int j = 0; j < expression.length(); j++) {
char c = expression.charAt(j);
if(c == '0' || c == '1') {
n = Character.getNumericValue(c);
nIndex = j;
break;
}
}
// n 앞의 느낌표 개수 세기
a = nIndex;
// n 뒤의 느낌표 개수 세기
b = expression.length() - (nIndex + 1);
int result;
if(b > 0) { // n 뒤에 느낌표가 있어서 팩토리얼 연산이 발생
// n!은 항상 1이 됨 (0! = 1, 1! = 1)
// 이제 1에 a개의 논리 반전 연산을 적용
if(a % 2 == 0) { // a가 짝수이면 1은 1 유지
result = 1;
} else { // a가 홀수이면 1은 0으로 반전
result = 0;
}
} else { // n 뒤에 느낌표가 없어서 팩토리얼 연산이 없음
// n에 a개의 논리 반전 연산을 적용
// 이는 n ^ (a % 2)와 동일
result = n ^ (a % 2);
}
bw.write(result + "\n");
}
bw.flush();
br.close();
bw.close();
}
}
코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.