알고리즘/백준

[백준] 3273: 두 수의 합 (JAVA)

김호록님 2024. 6. 1. 15:39

문제

n개의 서로 다른 양의 정수 a1, a2, ..., an으로 이루어진 수열이 있다. ai의 값은 1보다 크거나 같고, 1000000보다 작거나 같은 자연수이다. 자연수 x가 주어졌을 때, ai + aj = x (1 ≤ i < j ≤ n)을 만족하는 (ai, aj)쌍의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 수열의 크기 n이 주어진다. 다음 줄에는 수열에 포함되는 수가 주어진다. 셋째 줄에는 x가 주어진다. (1 ≤ n ≤ 100000, 1 ≤ x ≤ 2000000)

출력

문제의 조건을 만족하는 쌍의 개수를 출력한다.

 

풀이1 (틀림)

시간 초과 각인데 .. 하고 일단 이중 for문으로 풀었다가 역시나 시간 초과

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());
        int[] arr = new int[n];
        int cnt = 0;

        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(st.nextToken()); // 배열에 수 넣기
        }

        int x = Integer.parseInt(br.readLine());

        for (int i = 0; i < n; i++) {
            for (int j = i+1; j < n; j++) {
                if (arr[i] + arr[j] == x) {
                    cnt++;
                    arr[i] = -1;
                    arr[j] = -1;
                }
            }
        }
        System.out.println(cnt);
    }
}

 

풀이2 (맞음)

알고리즘 분류에 나와있는 투포인터를 사용해보기로 했다.

잘 모르는 알고리즘이라 다른 블로그 글을 참고했다. 감사합니다 :)

https://adjh54.tistory.com/384

 

[Java/알고리즘] 투 포인터 알고리즘(Two Pointer Algorithm) 이해하기 -1 : 종류, 활용방안

해당 글에서는 투 포인터 알고리즘에 대해 이해를 돕기 위해 작성한 글입니다. 1) 투 포인터 (Two Pointer Algorithm) 💡 투 포인터 (Two Pointer Algorithm) - 배열이나 리스트에서 '두 개의 포인터'를 사용하

adjh54.tistory.com

투포인터를 그대로 적용하면 되는 문제였다.

 

정답 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());
        int[] arr = new int[n];
        int cnt = 0;
        int start = 0;
        int end = n - 1; // 투포인터 알고리즘을 위한 시작과 끝
        int sum = 0; // 현재 합

        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(st.nextToken()); // 배열에 수 넣기
        }

        int x = Integer.parseInt(br.readLine()); // 타겟

        Arrays.sort(arr); // 정렬

        while (start < end) { // start가 end보다 작을 때까지
            sum = arr[start] + arr[end];
            if (sum == x) {
                cnt++;
                start++;
                end--;
            } else if (sum < x) {
                start++;
            } else {
                end--;
            }
        }
        System.out.println(cnt);
    }
}

 

알게 된 점

- 투포인터 알고리즘