[백준] 3273번 - 두 수의 합 (Silver 3)
업데이트:
문제 링크
문제 설명
수열 $a_1, a_2, \cdots, a_n$과 자연수 $x$가 주어져 있을 때, $a_i + a_j = x$인 $(a_i, a_j) (1 \leq i < j \leq n)$ 쌍의 개수를 구한다.
정답 코드 및 설명
투 포인터 알고리즘을 사용한다.
수열을 크기 순으로 정렬하고, $a_i$와 $a_j$를 가리키는 포인터 두 개를 생각하자.
- 양 끝에서 시작해서 두 수의 합이 $x$보다 크다면 큰 쪽을 작게 만들어야 하니 $j$를 하나 줄인다.
- 두 수의 합이 $x$보다 작다면 작은 쪽을 크게 만들어야 하니 $i$를 하나 늘린다.
- 두 수의 합이 정확히 $x$라면, 양쪽 다 한 칸씩 움직일 수 있는데 풀이에서는 $j$를 줄였다.
3번의 경우 바로 다음 단계에서 $i$가 늘어나게 되므로, 결과적으로 $i$를 늘리는 풀이와 동일하다.
$i$가 $j$보다 항상 작아야하므로, while문의 조건으로 $i < j$를 넣었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.io.*;
import java.util.*;
public class Main {
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 n = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
int[] a = new int[n];
for (int i = 0; i < n; i++)
a[i] = Integer.parseInt(st.nextToken());
int x = Integer.parseInt(br.readLine());
Arrays.sort(a);
bw.write(pair(a, x) + "");
bw.close();
}
static int pair(int[] a, int x) {
int i = 0, j = a.length - 1, count = 0;
while (i < j) {
if (a[i] + a[j] == x)
count++;
if (a[i] + a[j] >= x)
j--;
if (a[i] + a[j] < x)
i++;
}
return count;
}
}
댓글남기기