💻코딩테스트/백준

[백준/C++] 18870번 : 좌표 압축 (vector - unique, erase, lower_bound)

공대 컴린이 2023. 7. 4. 11:55
728x90

좌표 압축 

문제

수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다.

Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표 Xj의 개수와 같아야 한다.

X1, X2, ..., XN에 좌표 압축을 적용한 결과 X'1, X'2, ..., X'N를 출력해보자.

입력

첫째 줄에 N이 주어진다.

둘째 줄에는 공백 한 칸으로 구분된 X1, X2, ..., XN이 주어진다.

출력

첫째 줄에 X'1, X'2, ..., X'N을 공백 한 칸으로 구분해서 출력한다.

제한

  • 1 ≤ N ≤ 1,000,000
  • -109 ≤ Xi ≤ 109

예제 입력 1 

5
2 4 -10 4 -9

예제 출력 1 

2 3 0 3 1

예제 입력 2 

6
1000 999 1000 999 1000 999

예제 출력 2 

1 0 1 0 1 0

해당 문제를 처음엔 vector 하나와 set 하나로 푸려고 했는데, 내가 알던 find 함수는 vector의 함수였기 때문에 set 에서 사용할 수 없었다..!

 

따라서 vector변수를 두 개 선언하여 original 벡터를 copy 한 후, unique, erase를 이용해 중복을 제거해주었다.

 

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

using namespace std;

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	int N;
	cin >> N;

	vector<int> origin(N);
	for (int& o : origin)
		cin >> o;

	vector<int> copy(origin);
	sort(copy.begin(), copy.end());

	copy.erase(unique(copy.begin(), copy.end()), copy.end());

	for(int i = 0; i < N; i++)
	{
		cout << lower_bound(copy.begin(), copy.end(), origin[i])- copy.begin() << ' ';
	}
	return 0;
}

 

이때 vector 라이브러리의 erase 함수는 O(N)의 시간 복잡도를 가지고, unique도 O(N)의 시간복잡도를 갖는다.

 

unique를 통해 중복되는 원소를 vector에서 지우고 나면, vector에는 비어있는 공간이 생기기 때문에 보통 erase 함수를 같이 사용하여 빈 공간을 지워준다.

 

이렇게 중복을 지운 copy 벡터를 lower_bound로 앞에서부터 검사하며 일치하는 원소가 나올때마다 해당 원소의 인덱스를 출력하도록 구현하였다.


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

 

18870번: 좌표 압축

수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다. Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표 Xj의 개수와 같아야 한다. X1, X2, ..., XN에

www.acmicpc.net

728x90