알고리즘/백준

백준 2143 두 배열의 합(JAVA)

우리로 2020. 9. 16. 00:10

https://www.acmicpc.net/problem/2143

 

2143번: 두 배열의 합

첫째 줄에 T(-1,000,000,000 ≤ T ≤ 1,000,000,000)가 주어진다. 다음 줄에는 n(1 ≤ n ≤ 1,000)이 주어지고, 그 다음 줄에 n개의 정수로 A[1], …, A[n]이 주어진다. 다음 줄에는 m(1≤m≤1,000)이 주어지고, 그 다

www.acmicpc.net

 

 

 

자바는 코드가 너무 길다...

이 코드 길이 볼 때마다 파이썬으로 갈아타고 싶어진다 ㅠㅠ 투 포인터를 활용한 문제

import java.io.*;
import java.nio.Buffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class boj2143 {
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;

    static int n, m;

    static int pI(String s) {
        return Integer.parseInt(s);
    }

    /* srcArr에 있는 수를 조합해서 만든 부분합을 destArr에 넣습니다 */
    static void makeArr(ArrayList<Integer> destArr, int index, int[] srcArr, int sum) {
        if (index == srcArr.length) {
            return;
        }
        destArr.add(sum + srcArr[index]);
        makeArr(destArr, index + 1, srcArr, sum + srcArr[index]);
    }

    public static void main(String[] args) throws IOException {
        long t = Long.parseLong(new StringTokenizer(br.readLine()).nextToken());

        n = pI(new StringTokenizer(br.readLine()).nextToken());
        int[] nArr = new int[n];

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) nArr[i] = pI(st.nextToken());

        m = pI(new StringTokenizer(br.readLine()).nextToken());
        int[] mArr = new int[m];

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < m; i++) mArr[i] = pI(st.nextToken());

        // 지금까지 Input을 받았습니다.

        ArrayList<Integer> nTargetArr = new ArrayList<>();
        ArrayList<Integer> mTargetArr = new ArrayList<>();

        // 부분합 만들어주기
        for (int i = 0; i < nArr.length; i++) makeArr(nTargetArr, i, nArr, 0);
        for (int i = 0; i < mArr.length; i++) makeArr(mTargetArr, i, mArr, 0);

        // 정렬하기
        Collections.sort(nTargetArr);
        Collections.sort(mTargetArr);

        // 투 포인터
        int l = 0, r = mTargetArr.size() - 1;
        long count = 0;
        while (l < nTargetArr.size() && r >= 0) {
            long temp = nTargetArr.get(l) + mTargetArr.get(r);
            if (temp == t) {
                long ll = nTargetArr.get(l);
                long rr = mTargetArr.get(r);
                l++; r--;
                long lCount = 1, rCount = 1;

                while (l < nTargetArr.size() && ll == nTargetArr.get(l)) {
                    l++;
                    lCount++;
                }
                while (r >= 0 && rr == mTargetArr.get(r)) {
                    r--;
                    rCount++;
                }

                count += (lCount * rCount);

            } else if (temp < t) {
                l++;
            } else {
                r--;
            }
        }
        bw.write(count + "\n");
        bw.flush();
    }
}