네 개의 정수 배열 A, B, C, D가 있을 때
A[a] + B[b] + C[c] + D[d] == 0 을 만족하는 (a, b, c, d) 쌍의 개수를 구하는 문제
-1
배가 map에 존재하는지 탐색❌ 실패 사유:
해시맵 조회는 평균 O(1)이지만, 객체 박싱/GC/해시 충돌 등으로 시간초과 발생
-ab[i]
값이 존재하는지 binarySearch
로 체크❌ 실패 사유:
이분 탐색으로 값이 존재하는지는 확인 가능하지만,
몇 번 등장하는지를 정확히 세지 않아서 오답 발생
-ab[i]
값을 기준으로 ±0.5
를 기준으로 binarySearch 범위 계산❌ 실패 사유:
부동소수점 연산 오차로 인해 0.0 ≠ -0.0
처럼 비교 실패,
게다가 int
범위 초과 → long 사용 필요
ab[i] == 0.0
일 때 -0.0
비교 오류 → 0.0
로 강제long
으로 수정✅ 성공!
import java.io.*;
import java.util.*;
public class Main {
static int N;
static int[][] map;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
map = new int[N][4];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < 4; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
double[] ab = new double[N * N];
double[] cd = new double[N * N];
int idx = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
ab[idx] = map[i][0] + map[j][1];
cd[idx] = map[i][2] + map[j][3];
idx++;
}
}
Arrays.sort(cd);
long result = 0;
for (int i = 0; i < ab.length; i++) {
double key = (ab[i] == 0.0) ? 0.0 : -ab[i];
int lower = -(Arrays.binarySearch(cd, key - 0.5) + 1);
int upper = -(Arrays.binarySearch(cd, key + 0.5) + 1);
result += (upper - lower);
}
System.out.println(result);
}
}
import java.io.*;
import java.util.*;
public class Main {
static int N;
static int[][] map;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
map = new int[N][4];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < 4; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
int[] ab = new int[N * N];
int[] cd = new int[N * N];
int idx = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
ab[idx] = map[i][0] + map[j][1];
cd[idx] = map[i][2] + map[j][3];
idx++;
}
}
Arrays.sort(ab);
Arrays.sort(cd);
int start = 0;
int end = cd.length - 1;
long result = 0;
while (start < ab.length && end >= 0) {
int sum = ab[start] + cd[end];
if (sum == 0) {
int abVal = ab[start];
int cdVal = cd[end];
long abCount = 0, cdCount = 0;
while (start < ab.length && ab[start] == abVal) abCount++;
while (end >= 0 && cd[end] == cdVal) cdCount--;
result += abCount * cdCount;
} else if (sum < 0) {
start++;
} else {
end--;
}
}
System.out.println(result);
}
}
방법 | 시간복잡도 | 장점 | 단점 |
---|---|---|---|
이분 탐색 + 개수 카운팅 | O(N² log N) | 이론적으로 간단 | 부동소수점 오차, 예외처리 필요 |
✅ 투 포인터 | O(N²) | 구현 간단 + 빠름 | 정렬 필요 |
int
→ long
고려)존재 여부
가 아니라 개수
가 핵심