본문 바로가기
자바 코딩테스트

31458 초콜릿 중독 주의

by 백엔드 개발자 2025. 4. 2.

문제

 

 

이 문제에서 계산할 수식은 정수 하나와 0개 이상의 느낌표로 이루어져 있다. 정수는 0 또는 1이며, 느낌표는 정수의 앞이나 뒤에 올 수 있다. 이 수식을 계산하는 규칙은 다음과 같다.

  • n!은 의 팩토리얼이다. 0!=1, 1!=1로 정의된다.
  • !n은 의 논리 반전(logical not)이다. !0=1, !1=0으로 정의된다.
  • 팩토리얼이나 논리 반전이 중첩되어 있으면 중첩된 횟수만큼 계산하며, 
  • !n!과 같이 둘 다 사용된 경우에는 팩토리얼을 먼저 계산한다.
  • 예를 들어, !!n!!=!(!((n!)!))이다.

입력

첫 번째 줄에는 수식의 개수 T가 주어진다. (1≤T≤1000) 

두 번째 줄부터 T개의 수식이 한 줄에 하나씩 주어진다.

하나의 수식은 a개의 느낌표,

정수 n, b개의 느낌표가 공백 없이 순서대로 합쳐진 형태이다. 

 

출력

각 수식을 계산한 결과를 한 줄에 하나씩 출력한다.

 

0. 숫자를 입력 받는다

1. 수식을 하나씩 처리한다.

2. 숫자가 나올때까지 세서 논리반전의 개수를 구한다 

3. 숫자다음의 모든 느낌표의 개수를 구한다.

4. 팩토리얼 - 논리반전 개수를 구한다.

5. 구한 값이 음수이면 논리반전 그만큼 실행, 양수이면 1 반환

 

일일히 안세고 특정 숫자 양옆을 구하는 방법제

 

 

 

 

이 문제에서 계산할 수식은 정수 하나와 0$0$개 이상의 느낌표로 이루어져 있다. 정수는 0$0$ 또는 1$1$이며, 느낌표는 정수의 앞이나 뒤에 올 수 있다. 이 수식을 계산하는 규칙은 다음과 같다.

 

 n!은 n의 팩토리얼이다. 0!=1, 1!=1로 정의된다.

 !n은 n의 논리 반전(logical not)이다. !0=1, !1=0으로 정의된다.

팩토리얼이나 논리 반전이 중첩되어 있으면 중첩된 횟수만큼 계산하며, 

!n!과 같이 둘 다 사용된 경우에는 팩토리얼을 먼저 계산한다.

예를 들어, !!n!!=!(!((n!)!))이다.

입력

첫 번째 줄에는 수식의 개수 T$T$가 주어진다. (1≤T≤1000) 

 

두 번째 줄부터 T개의 수식이 한 줄에 하나씩 주어진다.

 

하나의 수식은 a개의 느낌표,

 

정수 n, b개의 느낌표가 공백 없이 순서대로 합쳐진 형태이다. 

 

 

 

출력

각 수식을 계산한 결과를 한 줄에 하나씩 출력한다.

 

 

 

0. 숫자를 입력 받는다

 

1. 수식을 하나씩 처리한다.

 

2. 숫자가 나올때까지 세서 논리반전의 개수를 구한다 

 

3. 팩토리얼은 개수에 상관없이 있기만 하면 1이 되니 존재하면 1

 

4. 논리반전도 짝수면 그수 그대로 홀수면 반대

 

 

 

내가 시도해본 방법은

1) 정규식으로 앞과 뒤의 ! 개수 구하기.

2) 팩토리얼은 1개만 있어도 1로 변한다. 그리고 논리반전은 홀수개일때만 한번 반전해주고 짝수개일때는 무시해주면 된다는 로직

이 2가지였는데, 정규식이 너무 복잡한 느낌이 들었다.


import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class 초콜릿중독주의31458 {
    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 count = Integer.parseInt(br.readLine());

        String data;
        int reverse = 0;
        int factorial = 0;

        int [] resultArray = new int[count];
        for(int i = 0 ; i< count; i ++) {
            int result = 0;
            Matcher matcher = Pattern.compile("(!*)(\\d+)(!*)").matcher(br.readLine());

           if(matcher.matches()){
               reverse = Optional.ofNullable(matcher.group(1)).map(String::length).orElse(0);
               factorial = Optional.ofNullable(matcher.group(3)).map(String::length).orElse(0);
               result = Integer.parseInt(matcher.group(2));
               if (factorial > 0 ) {
                   result = 1;
               }

               if (reverse % 2 == 1) {
                   result = (reverse(result));
               }

               resultArray[i] = result;
           }

        }

        for(int i = 0 ; i< count; i ++) {
              /*  bw.write(resultArray[i]);
                bw.flush();*/
            System.out.println(resultArray[i]);
        }
        br.close();
        bw.close();
    }

    private static int reverse(int result) {
        if (result == 1) {
         return 0;
        }
        return 1;
    }
}

 

 

참고 코드( 92034428번 소스 코드)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		int t = Integer.parseInt(br.readLine());

		for (int i = 0; i < t; i++) {
			String input = br.readLine().strip();
			boolean n = input.endsWith("!")?true:input.charAt(input.length()-1) == '1';
			int idx = 0;
			while (input.charAt(idx++) == '!') n = !n;
			sb.append(n==true?1:0).append("\n");
		}

		System.out.println(sb);
		br.close();
	}
}

 

1. 숫자가 1이거나 팩토리얼로 인해서 뒤에 !이 하나라도 존재하면 true, 아니면 false. 이렇게 한 이유는 토글 시키기 위해서였다.

2. !가 나올때까지 논리 반전을 시킨다.

3. String builder.append로 n값에 따라 1이나 0과 줄바꿈을 더한다.

 

 

 

배운 것

 

1. 여러개를 입력받아서 한번에 쭉 출력할때는 bw.write 보다는

StringBuilder를 사용해서 append로 쌓은 다음에 출력하는 것도 방법이 될 수 있겠다.

2. 0 과 1이 논리 반전되는걸 토글로 생각할 수 있는 점