BOJ 10825 - 국영수
-
<tuple>
이 있다는 것을 알게 되었다. -
pair<int, pair<string, int>>
와 같은 선언과s.first.second.second
와 같은 귀찮고 보기 힘든 내용을 싹 정리해준다. -
소스코드만 봐도 tuple에 관해 직관적으로 이해할 수 있기 때문에 코드를 먼저 보는게 나을 것 같다.
소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<tuple>
#include<string>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
typedef tuple<int, int, int, string> stds;
int main()
{
int n;
cin>>n;
vector<stds> s(n);
for(int i=0;i<n;i++){
string st;
int a, b, c;
cin>>st>>a>>b>>c;
s[i]=make_tuple(-a, b, -c, st);
}
sort(s.begin(), s.end());
for(auto it:s) cout<<get<3>(it)<<'\n';
}
<tuple>
의 함수들
tuple<VTypes...> make_tuple (Types&&... args)
make_pair
과 같은 역할의 함수다. 선언한tuple
의 type에 맞춰 호출하면 된다.
Types 뒤의 &&는 뭔가요??
명칭은 우측값 참조(Rvalue reference)라고 한다.
먼저 좌측/우측값에 대해 짚고 넘어가자면, C++기준으로 &을 통해 레퍼런스를 만들 수 있으면 Lvalue
고 Rvalue
는 그게 아닌 값들이다.
대입연산자 =
를 정의할 때 =
뒤에 오는 값이 Lvalue
냐 Rvalue
냐에 따라서 처리하는 방법이 달라진다. a=b에 대해 b가 Lvalue일 때는
Lvalue일 때는 Lvalue자체가 값이 아니고 어떤 값이나 인스턴스를 가리키는 레퍼런스다.
때문에 대입 연산을 할 때 로컬에서 생성된 레퍼런스에 대해 복제를 해서 복제된 리소스를 이용해야 한다.
하지만 Rvalue일 때는 Rvalue 자체가 값이기 때문에 복제를 할 필요 없이 바로 대입해서 연산 속도를 빠르게 만들 수 있다.
일단 이렇게만 이해했는데 제대로 한건가 모르겠다. 다음에 필요하면 다시 이해해보자.
-
tuple<CTypes...> tuple_cat (Tuples&&... tpls)
- 위의 코드에는 나와있지 않지만
tuple
두 개를 합쳐주는 역할이다.(string concatenation 같이) - Ex. (1, a, 2)와 (2, b, 3)을 파라미터로 넣으면 (1, a, 2, 2, b, 3)이 나옴
- 위의 코드에는 나와있지 않지만
-
typename tuple_element< I, tuple<Types...> >::type& get(tuple<Types...>& tpl) noexcept
typename tuple_element< I, tuple<Types...> >::type&& get(tuple<Types...>&& tpl) noexcept
typename tuple_element< I, tuple<Types...> >::type const& get(const tuple<Types...>& tpl) noexcept
vector
에서operator[]
의 역할을 대신한다.([]를tuple
에도 써봤는데 컴파일에러가 뜬다.tuple
에서[]
를 쓸바엔vector
를 써라 이런 느낌인 것 같다.)- Rvalue reference에 대해서도 오버로딩 되어있어
get<0>(mytuple)=1;
과 같은 코드도 편하게 사용할 수 있다.
-
tuple<Types&...> tie (Types&... args) noexcept
tuple
의 원소들을 각각 다른 변수에 한 번에 넣어준다.
Ex.
1 2
mytup=make_tuple(10, 20, 30); tie(a, b, c)=mytup;
-
tuple<Types&&...> forward_as_tuple (Types&&... args) noexcept
tuple
타입을 파라미터로 넣어야할 때make_tuple
을 사용하지 않고 전달할 수 있게 해준다.void print(tuple<int, string, int> tp)
가 정의되어 있을 때,
print(forward_as_tuple(1, string("asd"), 2))
로 호출이 가능하게 해준다.
풀고나서
- pair, string으로만 풀었을 때 180ms로 통과했고, tuple을 이용해서 풀었을 때 156ms로 통과했다.
- 시간을 정확히 재보지 않아서 단정지을 수는 없지만 (아마도) pair을 다중으로 사용하는 것보다는 tuple이 더 빠른 것 같다. 앞으로 자주 써야겠다.
Leave a comment