컴퓨터 사이언스/1고리즘

백준 20440 : 🎵니가 싫어 싫어 너무 싫어 싫어 오지 마 내게 찝쩍대지마🎵 - 1

저세상 개발자 2021. 8. 18. 00:25

https://www.acmicpc.net/problem/20440

 

20440번: 🎵니가 싫어 싫어 너무 싫어 싫어 오지 마 내게 찝쩍대지마🎵 - 1

첫째 줄에 지동이의 방에 출입한 모기의 마릿수 N(1 ≤ N ≤ 1,000,000)가 주어진다. 다음 N개의 줄에 모기의 입장 시각 TE과 퇴장 시각 TX이 주어진다. (0 ≤ TE < TX ≤ 2,100,000,000) 모기는 [TE, Tx)동

www.acmicpc.net

 

무지성 트리맵 자료구조를 사용하면 시간초과에 거의 근접한 성능으로 겨우 통과를 받을 수 있는 문제다.

트리맵이라는 자료구조 자체가 무거운 자료구조일 뿐만 아니라 key를 기준으로 정렬되어있지만 value를 기준으로 원하는 값을 찾고자 할때는 iterator를 이용한 선형탐색밖에 답이 없으므로 트리맵을 쓰는 것은 좋지 않다.

 

vector자료구조와 sort, unique, lower_bound 를 이용한 좌표압축 기법을 쓰는 것이 정해로 보인다. 다만 나는 이 문제를 풀면서 불필요한(?, 불필요한건 아니지만 임시로 사용되는 이 옳은 표현인 것 같다.) 배열에 메모리를 사용하고 싶지 않아서 고민 끝에 그냥 벡터 하나에 좌표값과 prefix_sum 값을 같이 넣어서 해결했다.

 

0. dp기법중 prefix_sum(누적합) 기법을 사용했다.

1. 모기가 들어오는 지점에 prefix_sum 값을 +1 해준다.

2. 모기가 나가는 지점에 prefix_sum 값을 -1 해준다.

3. 모든 지점을 좌표값 기준 오름차순으로 순회하면서 차례대로 이전 인덱스의 prefix_sum 값을 현재 지점의 prefix_sum 값에 더한다.

4. 벡터의 사이즈만큼 모두 순회했다면 벡터의 각 지점에는 현재 모기가 몇 마리 있는지 갱신되어있다.

 

+5. 나는 좌표압축을 하지 않았기 때문에 좌표가 unique하지 않다. 따라서 while문 안에서 while문을 한 번 더 돌면서 좌표가 같은 값을 모두 더해줬다.

 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int n;
vector<pair<int,int>> prefix_sum;

void solution() {
	int in, out;
	int cur_pos, prev, max_val;
	int idx, start, end = 0;

	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> in >> out;
		prefix_sum.emplace_back(in, 1);
		prefix_sum.emplace_back(out, -1);
	}

	sort(prefix_sum.begin(), prefix_sum.end());
	
	idx = 0, prev = 0, max_val = 0;
	while (idx < prefix_sum.size()) {
		cur_pos = prefix_sum[idx].first;
		//좌표 압축을 하지 않아 좌표 값이 unique하지 않음
		//while문을 한 번 더 돌면서 좌표 값이 같은 동안 prefix_sum 값을 더해줌
		while (idx < prefix_sum.size()
			&& prefix_sum[idx].first == cur_pos) {
			prev += prefix_sum[idx].second;
			++idx;
		}

		if (prev > max_val) {
			max_val = prev;
			start = cur_pos;
			end = 0;
		}
		else if (prev < max_val) {
			if (!end) end = prefix_sum[idx - 1].first;
		}
	}
	cout << max_val << '\n';
	cout << start << ' ' << end << '\n';
}

int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	solution();

	return 0;
}
메모리: 26728 kb 시간: 300 ms