백준 2212, 센서 - Greedy
https://www.acmicpc.net/problem/2212
풀이 ① - SensorDistance[]
정의
1. 아이디어
- 인접한 센서 간 거리가 먼 곳에 집중국을 설치해나감
=> 인접한 센서 간 거리가 가장 먼 곳들을 분리하여, 집중국을 할당하는 느낌
=> 인접한 센서 간 거리가 가장 먼 곳들을 분리하여, 집중국을 할당하는 느낌
1) 센서 배열을 센서 위치 빠른 순으로 정렬
2) 인접 센서 간 거리를 계산하여 배열에 저장 후, 거리 큰 순으로 정렬
SensorDistance[]
=>SensorDistance
: 2개 센서 번호 (sensor1
,sensor2
), 2개 센서의 거리distance
3) 정렬된 센서 간 거리 배열에서 큰 거리 순으로 (k-1) 개 선택
- 집중국 설치, 센서 영역 분할
List<Integer>
에SensorDistance[]
의 각 원소에서sensor1
저장
2. 자료구조
SensorDistance[]
: 인접 센서 간 거리, 2개 센서 번호 저장한 배열List<Integer>
,ArrayList<Integer>
: 집중국 설치할 위치 (거리가 먼 인접 센서 분할) 저장
3. 시간 복잡도
- 센서 빠른 위치 순으로 정렬: O(n log n)
- 인접 센서 간 거리 배열 정렬: O(n log n)
- 영역 최소 합 계산: O(2k)
=> 총 시간 복잡도: O(2n log n + 2k)
=> n, k 최대값 대입: 대충 (2 x 10^5 + log 2^13) + (2 x 10^3)
= (26 x 10^5) + (2 x 10^3) = (26 x 10^5) + (2 x 10^3) << 2억
코드
import java.io.*;
import java.util.*;
class SensorDistance implements Comparable<SensorDistance> {
public int sensor1, sensor2;
public int distance;
public SensorDistance(int sensor1, int sensor2, int distance) {
this.sensor1 = sensor1;
this.sensor2 = sensor2;
this.distance = distance;
}
public int compareTo(SensorDistance sd) {
int distanceDiff = sd.distance - this.distance;
if (distanceDiff != 0) // 거리 큰 순
return distanceDiff;
else // 거리가 같으면, sensor 번호가 빠른 순
return this.sensor1 - sd.sensor1;
}
}
public class Main {
static int n, k; // 센서 개수 n, 집중국 개수 k
static int[] sensors; // 각 센서의 위치
static int minSum; // 출력: 영역 길이 최소 합
static SensorDistance[] sds; // 인접한 센서 간 거리
static List<Integer> herbList = new ArrayList<>();
static void solution() {
// 인접 센서 간 거리 큰 순으로 (k-1)개 선택
for (int i = 0; i < k - 1; i++)
herbList.add(sds[i].sensor1);
// 각 집중국의 영역 계산
int startIdx = 0;
for (int herbIdx : herbList) {
minSum += (sensors[herbIdx] - sensors[startIdx]);
startIdx = herbIdx + 1;
}
minSum += (sensors[n - 1] - sensors[startIdx]);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)
);
StringTokenizer st;
n = Integer.parseInt(br.readLine());
k = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
sensors = new int[n];
sds = new SensorDistance[n - 1];
for (int i = 0; i < n; i++)
sensors[i] = Integer.parseInt(st.nextToken());
// 예외 처리) 집중국 개수 k >= 센서 개수 n 인 경우, 센서마다 집중국 설치
if (k >= n) {
System.out.println(0);
return;
}
Arrays.sort(sensors); // 센서 위치 빠른 순으로 정렬
// 인접 센서 간 거리 저장
for (int i = 1; i < n; i++) {
sds[i - 1] = new SensorDistance(
i - 1, i, Math.abs(sensors[i - 1] - sensors[i])
);
}
Arrays.sort(sds); // 인접 센서 간 거리 큰 순으로 정렬
solution();
System.out.println(minSum);
}
}
풀이 ② - Integer[]
에 거리만 저장
1. 아이디어
- 인접한 센서 간 거리가 먼 곳에 집중국을 설치해나감
=> 인접한 센서 간 거리가 가장 먼 곳들을 분리하여, 집중국을 할당하는 느낌
=> 인접한 센서 간 거리가 가장 먼 곳들을 분리하여, 집중국을 할당하는 느낌
1) 센서 배열을 센서 위치 빠른 순으로 정렬
2) 인접 센서 간 거리를 계산하여 배열에 저장 후, 거리 큰 순으로 정렬
Integer[] distances
3) 정렬된 센서 간 거리 배열에서 큰 거리 순으로 (k-1) 개 제외하고, 나머지 거리들을 모두 더한 값이 최소 합
- 정렬된 배열에서
distances[0]
~distances[k-2]
는 합에서 제외"집중국을 설치한다"
= "해당 인접 센서 간의 거리는 합에서 제외한다" distances[k-1]
~distances[끝]
까지 모든 거리들을 더함
2. 자료구조
Integer[]
: 인접 센서 간 거리 배열
=> 값이 큰 순으로 정렬하기 위해int[]
가 아닌,Integer[]
사용
3. 시간 복잡도
- 센서 빠른 위치 순으로 정렬: O(n log n)
- 인접 센서 간 거리 배열 정렬: O(n log n)
- 영역 최소 합 계산: O(k)
=> 총 시간 복잡도: O(2n log n + k)
=> n, k 최대값 대입: 대충 (2 x 10^5 + log 2^13) + 10^3
= (26 x 10^5) + 10^3 = (26 x 10^5) + 10^3 << 2억
코드
import java.io.*;
import java.util.*;
public class Main2 {
static int n, k; // 센서 개수 n, 집중국 개수 k
static int[] sensors; // 각 센서의 위치
static Integer[] distances; // 인접 센서 간 거리
static int minSum; // 출력: 영역 길이 최소 합
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)
);
StringTokenizer st;
n = Integer.parseInt(br.readLine());
k = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
sensors = new int[n];
distances = new Integer[n - 1];
for (int i = 0; i < n; i++)
sensors[i] = Integer.parseInt(st.nextToken());
// 예외 처리) 집중국 개수 k >= 센서 개수 n 인 경우, 센서마다 집중국 설치
if (k >= n) {
System.out.println(0);
return;
}
Arrays.sort(sensors); // 센서 위치 빠른 순으로 정렬
// 인접 센서 간 거리 저장
for (int i = 1; i < n; i++)
distances[i - 1] = Math.abs(sensors[i - 1] - sensors[i]);
Arrays.sort(distances, Collections.reverseOrder()); // 인접 센서 간 거리 큰 순으로 정렬
// Arrays.sort(distances, (d1, d2) -> d2 - d1);
// 인접 센서 간 거리 큰 순으로 (k-1)개 제외하고, 나머지 모두 더함
for (int i = k - 1; i < n - 1; i++)
minSum += distances[i];
System.out.println(minSum);
}
}
Author And Source
이 문제에 관하여(백준 2212, 센서 - Greedy), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@silver_star/백준-2212-센서-Greedy저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)