https://www.acmicpc.net/problem/18869
18869번: 멀티버스 Ⅱ
M개의 우주가 있고, 각 우주에는 1부터 N까지 번호가 매겨진 행성이 N개 있다. 행성의 크기를 알고 있을때, 균등한 우주의 쌍이 몇 개인지 구해보려고 한다. 구성이 같은데 순서만 다른 우주의 쌍
www.acmicpc.net
- 같은 우주임을 판별하려면 행성들을 정렬했을 때, 기존 인덱스 값을 기준으로 비교하면 된다.
- ex, 행성1: 10, 30, 20 ➡️ 정렬 후 인덱스 값: 0, 2, 1
- ex, 행성2: 30, 20, 10 ➡️ 정렬 후 인덱스 값: 2, 1, 0
- ex, 행성3: 20, 50, 30 ➡️ 정렬 후 인덱스 값: 0, 2, 1
- 결과: 행성1과 행성3은 균등함
- 따라서 기존 배열(ex, 10, 30, 20)과 정렬된 배열(ex, 10, 20, 30)이 있을 때, 정렬된 배열에 기존 배열의 값이 몇 번째 인덱스에 있는지 확인하면 된다. (ex, 0, 2, 1)
- 인덱스를 찾을 때 행성 개수 n개를 순차 탐색하면 O(n^2)의 시간 복잡도가 발생한다. 따라서 전체 코드의 시간 복잡도는 O(m * n^2)가 되어 시간 초과가 발생한다. 따라서 인덱스를 찾을 때 이분탐색을 통해 찾아야 한다O(nlogn).
- 인덱스 값들로 이뤄진 배열 간에 비교할 때, 배열 간 비교는 Arrays.equals()를 사용하면 된다. 일차원 배열의 값들을 비교해주는 메소드이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
// 시간 복잡도: O(m * nlogn)
public class Main {
static int m; // 우주 개수
static int n; // 행성 개수
static int[][] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
m = Integer.parseInt(st.nextToken());
n = Integer.parseInt(st.nextToken());
arr = new int[m][n];
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int[] oneArr = new int[n];
for (int j = 0; j < n; j++) {
oneArr[j] = Integer.parseInt(st.nextToken());
}
arr[i] = oneArr;
}
for (int i = 0; i < arr.length; i++) {
int[] oneArr = arr[i];
int[] sortedArr = oneArr.clone();
Arrays.sort(sortedArr);
// 이분탐색
for (int j = 0; j < oneArr.length; j++) {
oneArr[j] = calculateIdx(sortedArr, oneArr[j]);
}
}
int answer = 0;
for (int i = 0; i < m; i++) {
for (int j = i + 1; j < m; j++) {
if (Arrays.equals(arr[i], arr[j])) { // Arrays.equals: 두 배열의 값 비교
answer++;
}
}
}
System.out.println(answer);
}
// sortedArr 배열에서 target 숫자가 있는 인덱스를 찾아서 반환
private static int calculateIdx(int[] sortedArr, int target) {
int minIdx = 0;
int maxIdx = sortedArr.length - 1;
int midIdx = 0;
while (minIdx <= maxIdx) {
midIdx = (minIdx + maxIdx) / 2;
if (sortedArr[midIdx] == target) {
return midIdx;
} else if (sortedArr[midIdx] < target) {
minIdx = midIdx + 1;
} else {
maxIdx = midIdx - 1;
}
}
return -1;
}
}
'CS > Algorism' 카테고리의 다른 글
[백준] 2003. 수들의 합2 (0) | 2024.01.21 |
---|---|
[백준] 2467. 용액 (2) | 2024.01.19 |
[백준] 16401. 과자 나눠주기 (0) | 2024.01.18 |
[프로그래머스] 조이스틱 (1) | 2024.01.13 |
[백준] 1912. 연속합 (0) | 2024.01.12 |