본문 바로가기
PS/BOJ

[자바] 백준 10448 - 유레카 이론 (java)

by Nahwasa 2023. 12. 1.

목차

    문제 : boj10448

     

     

    필요 알고리즘

    • 브루트 포스
      • 단순히 모든 경우를 살펴보는 것으로 풀 수 있는 문제이다.

    ※ 제 코드에서 왜 main 함수에 로직을 직접 작성하지 않았는지, 왜 Scanner를 쓰지 않고 BufferedReader를 사용했는지 등에 대해서는 '자바로 백준 풀 때의 팁 및 주의점' 글을 참고해주세요. 백준을 자바로 풀어보려고 시작하시는 분이나, 백준에서 자바로 풀 때의 팁을 원하시는 분들도 보시는걸 추천드립니다.

     

     

    풀이

      문제를 약간 바꿔서 생각해보자.

    X개의 숫자가 주어진다. 그 중 3개를 합한 값이 N인 경우가 있다면 1, 없다면 0을 출력하는 문제이다.

    이 때, 단순하게 3개의 수를 골라 합쳐보면서 정말 있는지 없는지 확인해본다고 하자. 이 경우 시간 복잡도는 O(X^3) 이고, X가 충분히 작다면 이 풀이는 문제없이 가능한 브루트포스 풀이이다.

     

      다시 원래의 문제로 돌아오자. 뭔가 복잡해보이는 Tn 이라는 수식이 있는데, 딱히 상관없다. 위에서 말한 X개의 숫자가 주어지는 것과 마찬가지다. Tn은 이 문제에서 음수가 될 수 없으므로, 단순히 최대 K이하까지의 Tn만 구해두면 위에서 X개의 숫자가 주어진 것과 동일한 상황이란거다.

     

      Tn에서 n=44일 때 990이라는 값이 나온다. 즉, n=1부터 n=44까지만 Tn을 구하면 되며, 위의 예시에서 X는 44인 셈이다. O(44^3)으로 풀 수 있는 브루트포스 문제이다.

     

      로직은 다음과 같다.

    1. n=1부터 n=44까지 Tn을 미리 구해둔다.

    int[] t = new int[LEN];
    for (int i = 1; i < LEN; i++) t[i] = i*(i+1)/2;

     

    2. K를 입력받아, 44개의 Tn들을 3중 for문으로 직접 합쳐보다가 K와 동일해지면 1을 출력하면 된다. 없었다면 0을 출력하면 된다.

    private boolean possible(final int[] t, final int n) {
        for (int i = 1; i < LEN; i++)
            for (int j = i; j < LEN; j++)
                for (int k = j; k < LEN; k++)
                    if (t[i]+t[j]+t[k] == n)
                        return true;
        return false;
    }

     

    코드 : github

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    public class Main {
        static BufferedReader br = new BufferedReader(new InputStreamReader(System.in), 1<<16);
        private static final int LEN = 45;
    
        public static void main(String[] args) throws Exception {
            new Main().solution();
        }
    
        public void solution() throws Exception {
            int[] t = new int[LEN];
            for (int i = 1; i < LEN; i++) t[i] = i*(i+1)/2;
    
            int tc = Integer.parseInt(br.readLine());
            StringBuilder sb = new StringBuilder();
            while (tc-->0) {
                int n = Integer.parseInt(br.readLine());
                sb.append(possible(t, n) ? 1 : 0).append('\n');
            }
            System.out.print(sb);
        }
    
        private boolean possible(final int[] t, final int n) {
            for (int i = 1; i < LEN; i++)
                for (int j = i; j < LEN; j++)
                    for (int k = j; k < LEN; k++)
                        if (t[i]+t[j]+t[k] == n)
                            return true;
            return false;
        }
    
    }

     

    댓글