[백준/C++] 18870번 : 좌표 압축 (vector - unique, erase, lower_bound)
좌표 압축
문제
수직선 위에 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