https://www.acmicpc.net/problem/18870
18870번: 좌표 압축
수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다. Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표의 개수와 같아야 한다. X1, X2, ..., XN에 좌
www.acmicpc.net
stl vector에 대해서 더 공부할 수 있던 문제였다.
처음엔 vector<pair<int, int>> v로 선언해서 {X, 순서}를 저장하려고 했는데, 풀다보니까 순서를 굳이 저장할 필요가 없어져서 vector<int> v로 바꾸어 풀었다.
참고로 pair로 선언된 vector를 sort함수로 정렬할때 compare함수를 따로 작성안하면 first 값을 기준으로 정렬 된다고함!!
vector
unique 함수
unique 함수는 <algorithm>헤더에 포함되어 있으며, vector의 중복된 원소를 제거할 때 사용할 수 있는 함수이다.
ForwardIterator unique (ForwardIterator first, ForwardIterator last);
사용할때는 vector가 정렬된 상태여야 한다.
#include <algorithm> #include <vector> #include <iostream> using namespace std; int main(void){ vector<int> v = {9, 5, 3, 4, 4, 3, 2, 1, 5, 5, 6}; sort(v.begin(), v.end()); unique(v.begin(), v.end()); for(auto c : v){ cout << c << ' '; } //1 2 3 4 5 6 9 5 5 6 9 출력 }
위의 결과를 보면 중복된 수는 뒤쪽에 저장되는데, unique 함수는 이 중복된 수의 시작주소를 반환한다.
erase 함수와 같이 사용하면 뒤쪽 중복된 원소들을 지울 수 있다.
erase 함수
erase 함수는 vector 컨테이너에 포함되며, vector의 특정 범위의 원소를 지울때 사용할 수 있다.
iterator erase (const_iterator position); //단일 위치를 지우는데 사용 iterator erase (const_iterator first, const_iterator last); //[first, last)를 지우는데 사용
unique 함수와 연계하면 다음과같이 사용가능하다.
이때의 first 인자는 v벡터에서 unique함수가 반환한 중복되는 값의 시작점이 되며, erase 함수를 이용해 v에서 중복된 값들을 삭제한다.
v.erase(unique(v.begin(), v.end()), v.end());
lower_bound, upper_bound함수
<algorithm> 헤더에 포함되어있다.
이진탐색에 기반하므로 오름차순으로 벡터가 정렬되어 있어야 사용할 수 있다.
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val); ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val);
두 함수는 조금 비슷한데,
lower_bound 함수는 val보다 작지 않은(==크거나 같은) [first, last)범위의 첫번째 요소를 가리키는 반복자를 반환한다.
upper_bound 함수는 val보다 큰 [first, last) 범위의 첫번째 요소를 가리키는 반복자를 반환한다.
반환되는 iterator에서 vector의 첫번재 원소를 가리키는 주소인 v.begin()을 빼면 인덱스를 만들수 있다.
만약 v 벡터의 k값의 인덱스를 찾고자 한다면,
lower_bound(v.begin(), v.end(), k) - v2.begin();
최종 코드
#include <bits/stdc++.h> using namespace std; int main(void){ ios::sync_with_stdio(false); cin.tie(NULL); vector<int> v; int N; cin >> N; for(int i = 0; i < N; i++){ int X; cin >> X; v.push_back(X); } vector<int> v2 = v; //벡터를 복사 sort(v2.begin(), v2.end()); //오름차순 정렬 v2.erase(unique(v2.begin(), v2.end()), v2.end()); //중복되는 원소 제거 for(int i = 0; i < N; i++){ cout << lower_bound(v2.begin(), v2.end(), v[i]) - v2.begin() << ' '; //인덱스메겨서 출력 } }
'알고리즘 > BAEKJOON' 카테고리의 다른 글
[백준] 2609번 최대공약수와 최소공배수 -C++ (0) | 2022.02.18 |
---|---|
[백준] 2579번 계단오르기 -C++ (0) | 2022.02.15 |
[백준] 11729번 하노이 탑 이동 순서 -자바(JAVA) (0) | 2022.01.24 |
[백준] 15829번 Hashing -자바(JAVA) (0) | 2022.01.19 |
[백준] 4673번 셀프 넘버 -자바(JAVA) (2) | 2022.01.19 |