๊ธฐ๋ก๋ฐฉ

BOJ_2143 : ๋‘ ๋ฐฐ์—ด์˜ ํ•ฉ ๋ณธ๋ฌธ

CodingTest/Java

BOJ_2143 : ๋‘ ๋ฐฐ์—ด์˜ ํ•ฉ

Soom_1n 2024. 4. 10. 14:03

๐Ÿ”ธ ๋ฌธ์ œ ๋ถ„์„ ๐Ÿ”ธ

  • ๋‘ ๋ฐฐ์—ด A์™€ B์˜ ๋ถ€๋ฐฐ์—ด์˜ ํ•ฉ์œผ๋กœ T๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

๐Ÿ”ธ ๋ฌธ์ œ ํ’€์ด ๐Ÿ”ธ

  • ๋ถ€๋ฐฐ์—ด์„ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋ˆ„์ ํ•ฉ์„ ์ด์šฉํ•œ๋‹ค.
    • ์ž…๋ ฅ ๋ฐฐ์—ด์˜ ์›์†Œ๋Š” ์ตœ๋Œ€ 1,000์ด๋ฏ€๋กœ, intํ˜•์œผ๋กœ 2๊ฐœ์˜ ๋ฐฐ์—ด์„ ์„ ์–ธํ•ด์„œ 2,000 x 4Byte = 8KB๊ฐ€ ์“ฐ์ธ๋‹ค.
  • ๋ฐฐ์—ด A์™€ B์˜ ๋ˆ„์ ํ•ฉ์„ ๋งŒ๋“  ๋’ค, ๋ชจ๋“  ๋ถ€๋ฐฐ์—ด์˜ ํ•ฉ์„ ๊ตฌํ•œ๋‹ค.
    • A์˜ ๋ถ€๋ฐฐ์—ด์˜ ์ˆ˜๋Š” A์˜ ์›์†Œ ์ˆ˜ n๊ฐœ ์ค‘์—์„œ ์‹œ์ž‘๊ณผ ๋ ์ธ๋ฑ์Šค 2๊ฐ€์ง€๋ฅผ ๋ฝ‘๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜์ด๋‹ค. ์ด๋•Œ ์ค‘๋ณต ๊ฐ€๋Šฅํ•˜๋‹ค.
      ์ค‘๋ณต ์กฐํ•ฉ ๊ณต์‹ nHr =  (n+r-1)! / r!(n-1)! ์—์„œ r=2 ์ด๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
      (n+1)! / 2(n-1)!
      = n(n+1) / 2 
    • ๋”ฐ์ง€๊ณ ๋ณด๋ฉด 1~n๊นŒ์ง€์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ์ดํ•ญ๊ณ„์ˆ˜์˜ ๊ณต์‹๊ณผ ๊ฐ™๋‹ค. 2์ค‘ for๋ฌธ์„ ๋ดค์„๋•Œ ๋” ์ง๊ด€์ ์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์•ˆ์ชฝ for๋ฌธ์˜ ๋ฐ˜๋ณต ์ˆ˜๊ฐ€ n, n-1, n-2, ... , 1 ์ˆœ์œผ๋กœ ์ค„์–ด๋“ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
    • ์—ฌ๊ธฐ์„œ๋Š” n์ด ์ตœ๋Œ€ 1000์ด๋ฏ€๋กœ, 1000 * 1001 / 2 ํ•ด์„œ ์ตœ๋Œ€ ๋ฐฐ์—ด ์ˆ˜๊ฐ€ 500,500 ์ด๊ณ , A B 2๊ฐœ๋‹ˆ๊นŒ 1,001,000์˜ ๋ฐฐ์—ด์ด ํ•„์š”ํ•˜๋‹ค.
      int๋กœ ๋”ฐ์ง€๋ฉด 4,004,000๋ฐ”์ดํŠธ = 4,004KB = ์•ฝ 4MB ์ด๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์— ์—ฌ์œ ๋กญ๋‹ค.
  • ๋งˆ์ง€๋ง‰์œผ๋กœ A์˜ ๋ถ€๋ฐฐ์—ด๊ณผ B์˜ ๋ถ€๋ฐฐ์—ด์˜ ํ•ฉ์ด T๊ฐ€๋˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•œ๋‹ค.
    • ๋‘ ํ•ฉ์ด T๊ฐ€ ๋˜๋„๋ก ๋งค์นญ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ํˆฌ ํฌ์ธํ„ฐ์™€ ์ด์ง„ํƒ์ƒ‰ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
    • ํˆฌ ํฌ์ธํ„ฐ๋Š” O(n)์ธ๋ฐ, ์—ฌ๊ธฐ์„œ๋Š” ์ค‘๋ณต ์›์†Œ๋„ ์ฒ˜๋ฆฌํ•ด ์ฃผ์–ด์„œ ๋น ๋ฅด๊ฒŒ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
      • ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณต์‹์œผ๋กœ ๊ณ„์‚ฐํ•œ๋‹ค.

        sum = subA[left] + subB[right]
         
      • ๋‘ ๋ถ€๋ฐฐ์—ดํ•ฉ์˜ ํ•ฉ์ด T์™€ ๊ฐ™์œผ๋ฉด, ์ค‘๋ณต ์›์†Œ๊นŒ์ง€ ํ™•์ธํ•ด์„œ ์นด์šดํŠธํ•œ๋‹ค.
      • T๋ณด๋‹ค ํฌ๋ฉด right - 1
      • T๋ณด๋‹ค ์ž‘์œผ๋ฉด left +1
    • ์ด์ง„ํƒ์ƒ‰์€ ํ‰๊ท  O(logn)์ด์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” ์ค‘๋ณต ์›์†Œ ๋•Œ๋ฌธ์— 4๋ฒˆ์”ฉ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์„œ ํˆฌ ํฌ์ธํ„ฐ๋ณด๋‹ค ๋Š๋ฆฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.
      • subA[i]๋ฅผ ๊ธฐ์ค€๊ฐ’ as๋กœ ์„ค์ •ํ•œ๋‹ค. as = subA[i]
      • subA์—์„œ as์™€ ์ผ์น˜ํ•˜๋Š” ๊ตฌ๊ฐ„์˜ ๊ธธ์ด(์ผ์น˜ํ•˜๋Š” ์›์†Œ ์ˆ˜)๋ฅผ ๊ตฌํ•œ๋‹ค.
        • aTerm = upper_bound(subA, as) - lower_bound(subA, as)
        • upper_bound๋Š” as๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์œผ๋ฉด์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ˆ˜, lower_bound๋Š” as๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์œผ๋ฉด์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ˆ˜๋ฅผ ๊ตฌํ•œ๋‹ค.
        • ์ด๋•Œ as์™€ ์ผ์น˜ํ•˜๋Š” ์›์†Œ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ์ด๋ฉด, ๊ทธ ์ˆ˜๋ฅผ ์•Œ๋ ค์ฃผ๊ฒŒ ๋œ๋‹ค.
        • ๋งŒ์•ฝ as์™€ ์ผ์น˜ํ•˜๋Š” ์›์†Œ๊ฐ€ ์—†๋‹ค๋ฉด, ๋˜‘๊ฐ™์ด right๋ฅผ ๋ฐ˜ํ™˜ํ•ด aTerm์€ 0์ด ๋˜์–ด ๋ฒ„๋ฆฐ๋‹ค.
        • bTerm๋Š” T-as๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ตฌํ•ด์„œ aTerm๊ณผ ๊ณฑํ•˜๋ฉด, ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.
      • subA์˜ ์›์†Œ๋ฅผ ํ•˜๋‚˜์”ฉ ๊ธฐ์ค€์œผ๋กœ ๋„ฃ์–ด๋ณด๋ฉฐ ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋ˆ„์ ํ•œ๋‹ค.

๐Ÿ”ธ ํˆฌ ํฌ์ธํ„ฐ ์ฝ”๋“œ ๐Ÿ”ธ

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        // Input
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = null;

        int T = Integer.parseInt(br.readLine());
        int n = Integer.parseInt(br.readLine());
        int[] A = new int[n + 1];

        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= n; i++) {
            A[i] = Integer.parseInt(st.nextToken()) + A[i - 1]; // ๋ˆ„์ ํ•ฉ
        }

        int m = Integer.parseInt(br.readLine());
        int[] B = new int[m + 1];

        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= m; i++) {
            B[i] = Integer.parseInt(st.nextToken()) + B[i - 1]; // ๋ˆ„์ ํ•ฉ
        }

        // ๋ชจ๋“  ๋ถ€๋ฐฐ์—ด์˜ ํ•ฉ ๊ตฌํ•˜๊ธฐ
        int[] subA = new int[n * (n + 1) / 2]; // nC2 : ๋ถ€๋ฐฐ์—ด ์‹œ์ž‘๊ณผ ๋ ์ธ๋ฑ์Šค ๋ฝ‘๊ธฐ
        int[] subB = new int[m * (m + 1) / 2]; // mC2
        int idx = 0;

        for (int i = 1; i <= n; i++) { // A๋ฐฐ์—ด ๋ถ€๋ฐฐ์—ด ๊ตฌํ•˜๊ธฐ
            for (int j = i; j <= n; j++) {
                subA[idx++] = A[j] - A[i - 1]; // ๋ถ€๋ฐฐ์—ด์˜ ํ•ฉ ์ €์žฅ
            }
        }

        idx = 0;
        for (int i = 1; i <= m; i++) { // B๋ฐฐ์—ด ๋ถ€๋ฐฐ์—ด ๊ตฌํ•˜๊ธฐ
            for (int j = i; j <= m; j++) {
                subB[idx++] = B[j] - B[i - 1]; // ๋ถ€๋ฐฐ์—ด์˜ ํ•ฉ ์ €์žฅ
            }
        }

        // ํˆฌ ํฌ์ธํ„ฐ
        Arrays.sort(subA);
        Arrays.sort(subB);
        int left = 0;
        int right = subB.length - 1;
        long answer = 0;

        while (left < subA.length && right >= 0) {
            long as = subA[left];
            long bs = subB[right];
            long sum = as + bs;

            if (sum == T) {
                long ac = 0; // ๊ฐ™์€ ๊ฐ’ ์นด์šดํŠธ
                long bc = 0;
                while (left < subA.length && as == subA[left]) {
                    left++;
                    ac++;
                }
                while (right >= 0 && bs == subB[right]) {
                    right--;
                    bc++;
                }
                answer += ac * bc;
            } else if (sum > T) {
                right--;
            } else {
                left++;
            }
        }

        // Output
        bw.write(Long.toString(answer));
        bw.flush();
    }
}

 

๐Ÿ”ธ ์ด๋ถ„ ํƒ์ƒ‰ ์ฝ”๋“œ ๐Ÿ”ธ

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        // Input
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = null;

        int T = Integer.parseInt(br.readLine());
        int n = Integer.parseInt(br.readLine());
        int[] A = new int[n + 1];

        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= n; i++) {
            A[i] = Integer.parseInt(st.nextToken()) + A[i - 1]; // ๋ˆ„์ ํ•ฉ
        }

        int m = Integer.parseInt(br.readLine());
        int[] B = new int[m + 1];

        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= m; i++) {
            B[i] = Integer.parseInt(st.nextToken()) + B[i - 1]; // ๋ˆ„์ ํ•ฉ
        }

        // ๋ชจ๋“  ๋ถ€๋ฐฐ์—ด์˜ ํ•ฉ ๊ตฌํ•˜๊ธฐ
        int[] subA = new int[n * (n + 1) / 2]; // nC2 : ๋ถ€๋ฐฐ์—ด ์‹œ์ž‘๊ณผ ๋ ์ธ๋ฑ์Šค ๋ฝ‘๊ธฐ
        int[] subB = new int[m * (m + 1) / 2]; // mC2
        int idx = 0;

        for (int i = 1; i <= n; i++) { // A๋ฐฐ์—ด ๋ถ€๋ฐฐ์—ด ๊ตฌํ•˜๊ธฐ
            for (int j = i; j <= n; j++) {
                subA[idx++] = A[j] - A[i - 1]; // ๋ถ€๋ฐฐ์—ด์˜ ํ•ฉ ์ €์žฅ
            }
        }

        idx = 0;
        for (int i = 1; i <= m; i++) { // B๋ฐฐ์—ด ๋ถ€๋ฐฐ์—ด ๊ตฌํ•˜๊ธฐ
            for (int j = i; j <= m; j++) {
                subB[idx++] = B[j] - B[i - 1]; // ๋ถ€๋ฐฐ์—ด์˜ ํ•ฉ ์ €์žฅ
            }
        }

        // ์ด๋ถ„ ํƒ์ƒ‰
        Arrays.sort(subA);
        Arrays.sort(subB);
        long answer = 0;

        for (int i = 0; i < subA.length; i++) {
            long as = subA[i];
            long aTerm = upper_bound(subA, as) - lower_bound(subA, as);
            long bTerm = upper_bound(subB, T - as) - lower_bound(subB, T - as);
            answer += aTerm * bTerm;
            i += (int) (Math.abs(aTerm) - 1);
        }

        // Output
        bw.write(Long.toString(answer));
        bw.flush();
    }

    private static int upper_bound(int[] arr, long t) {
        int left = 0, right = arr.length;
        while (left < right) {
            int mid = (left + right) / 2;

            if (t >= arr[mid]) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return right;
    }

    private static int lower_bound(int[] arr, long t) {
        int left = 0, right = arr.length;
        while (left < right) {
            int mid = (left + right) / 2;

            if (t <= arr[mid]) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return right;
    }
}

๐Ÿ”ธ end ๐Ÿ”ธ

  •  ํˆฌ ํฌ์ธํ„ฐ ํ’€์ด์—์„œ, as์™€ bs์˜ ๊ณฑ์ด int๋ฒ”์œ„๋ฅผ ๋„˜์–ด์„œ๋ฉด์„œ 68% ํ‹€๋ ธ๋‹ค.
    • n๊ณผ m์ด 1,000 ์ผ ๋•Œ, subA์™€ sub์˜ ํฌ๊ธฐ๊ฐ€ 500,500์ด ๋˜๊ณ , ์ œ๊ณฑํ•˜๋ฉด 250,500,250,000๊ฐ€ ๋‚˜์˜ค๊ธฐ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
    • ๋ฐฑ์ค€ ์งˆ๋ฌธ๊ธ€์—์„œ ์›์ธ์„ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค.
  • ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ตœ๋Œ€ํ•œ ์ƒ๊ฐํ•ด ๋ณด์•˜๋Š”๋ฐ, ๋ˆ„์ ํ•ฉ๊นŒ์ง€๋Š” ์ƒ๊ฐํ–ˆ๊ณ  n์ด 1,000์ด๋‹ˆ๊นŒ ์ด๋ถ„ ํƒ์ƒ‰์„ ์ด์šฉํ•ด์•ผ ํ•˜์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ•˜๋‹ค๊ฐ€ ์ ์šฉ ๋ฒ•์„ ๋– ์˜ฌ๋ฆฌ์ง€ ๋ชปํ•ด ํ’€์ด ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ–ˆ๋‹ค.
    • ๋ˆ„์ ํ•ฉ ๋Œ€์‹  ํˆฌ ํฌ์ธํ„ฐ๋ฅผ ๋จผ์ € ๋– ์˜ฌ๋ ธ๋‹ค๊ฐ€ ์ •๋ ฌ์ด ๋˜์–ด์žˆ์ง€ ์•Š์•„์„œ ์•„๋‹ˆ๋‹ค ์‹ถ์—ˆ๋Š”๋ฐ, ํ•ฉ์ด T๊ฐ€ ๋˜๋Š” ๋‘ ์›์†Œ ์ฐพ๊ธฐ์—์„œ ๋‹ค์‹œ ์“ฐ์ผ ์ค„ ๋ชฐ๋ž๋‹ค.
    • ์ด๋ถ„ ํƒ์ƒ‰ ํ’€์ด๋„ ์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ๋œ ๋ถ€๋ถ„์ด์—ˆ๋Š”๋ฐ, ๋ฒ”์œ„๋ฅผ ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š”๊ฒŒ ๋†€๋ผ์› ๋‹ค.
728x90