백준 온라인 저지 | 10825번 국영수 | C++
10825번: 국영수
첫째 줄에 도현이네 반의 학생의 수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 1
www.acmicpc.net
1. 문제 접근
■ 1.1 tuple 자료 구조
학생마다 이름과 국어, 영어, 수학 점수가 주어진다. 구조체(structure)를 사용하여 네 가지 데이터를 다룰 수도 있지만, 조금 더 편리한 tuple 자료 구조를 사용하려고 한다. #include <tuple> 헤더 파일을 선언하고 이름과 국어, 영어, 수학 점수를 저장하는 데 가장 적절한 타입인 <string, int, int, int>로 데이터를 받는다.
■ 1.2 compare 사용자 정의 정렬
단순 오름차순, 내림차순이 아닌 주어진 조건에 맞도록 정렬하려면 compare 함수를 사용해야 한다. 비교할 tuple 자료 구조 a, b를 인자로 선언한다. 이때 compare 함수에 전달되는 두 인자 a, b는 const 참조로 선언하여 불필요한 복사로 인해 성능이 떨어지지 않도록 한다. compare 함수에서 오름차순(증가하는 순서)은 a < b를 반환하고 내림차순(감소하는 순서)은 a > b를 반환해야 한다.
2. 문제 풀이
- 학생 정보를 저장할 info 벡터를 정의하고 tuple 자료 구조로 학생 정보를 받아 info 벡터에 저장한다.
- sort 함수로 info 벡터를 정렬한다.
- 모든 점수가 같으면 이름 사전 순으로 증가하는 순서로 → a.이름 < b.이름
- 국어 점수와 영어 점수가 같으면 수학 점수가 감소하는 순서로 → a.수학 > b.수학
- 국어 점수가 같으면 영어 점수가 증가하는 순서로 → a.영어 < b.영어
- 모든 점수가 다르면 국어 점수가 감소하는 순서로 → a.국어 > b.국어
3. 문제 해결
#include <iostream>
#include <algorithm>
#include <vector>
#include <tuple>
using namespace std;
bool compare(const tuple<string, int, int, int>& a, const tuple<string, int, int, int>& b);
int N;
int main(void) {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N;
vector<tuple<string, int, int, int>> info(N);
// 학생 수만큼 이름, 국어, 영어, 수학 점수를 받습니다.
for (int i = 0; i < N; ++i) {
string name;
int korean, english, math;
cin >> name >> korean >> english >> math;
info[i] = { name, korean, english, math };
}
// 비교 함수에 근거하여 배열을 정렬합니다.
sort(info.begin(), info.end(), compare);
for (const auto& e : info) {
cout << get<0>(e) << '\n';
}
return 0;
}
// 주어진 조건에 맞도록 배열을 정렬합니다.
bool compare(const tuple<string, int, int, int>& a, const tuple<string, int, int, int>& b) {
if (get<1>(a) == get<1>(b)) {
if (get<2>(a) == get<2>(b)) {
if (get<3>(a) == get<3>(b)) {
// 모든 점수가 같으면 이름이 사전 순으로 증가하는 순서로 정렬합니다.
return get<0>(a) < get<0>(b);
}
// 국어와 영어 점수가 같으면 수학 점수가 감소하는 순서로 정렬합니다.
return get<3>(a) > get<3>(b);
}
// 국어 점수가 같으면 영어 점수가 증가하는 순서로 정렬합니다.
return get<2>(a) < get<2>(b);
}
// 국어 점수가 감소하는 순서로 정렬합니다.
return get<1>(a) > get<1>(b);
}
4. 문제 고찰
■ 4.1 tuple 자료 구조
tuple 자료 구조는 pair 자료 구조를 확장한 것으로 여러 가지 데이터를 묶음으로 처리할 수 있다. 예를 들어, 3차원 공간에서의 (x, y, z) 좌표를 저장하거나, 사람의 이름, 나이, 성적과 같은 개인 정보를 저장하는 데 유용하다. tuple 자료 구조는 #include <tuple> 헤더 파일을 선언해야 사용할 수 있다. tuple 자료 구조에 저장된 데이터는 두 가지 방법으로 접근할 수 있는데, 일반적으로 get<>() 함수를 사용하나 C++17 이상인 경우, 구조적 바인딩으로 tuple 자료 구조의 데이터에 각각 접근할 수 있다.
#include <tuple>
tuple<int, double, string> t;
t = { 10, 10.0, "10" };
// get<>() 함수로 데이터에 접근할 수 있습니다.
int i = get<0>(t);
double d = get<1>(t);
string s = get<2>(t);
// C++17 이상은 구조적 바인딩으로 데이터에 접근할 수 있습니다.
auto& [i, d, s] = t;
코딩 테스트에서 C++17을 지원하지 않는 경우, 구조적 바인딩을 사용할 수 없기 때문에 get<>() 함수를 명확하게 숙지하도록 하자.
'Data Structures and Algorithms > 백준 온라인 저지' 카테고리의 다른 글
백준 온라인 저지 | 10870번 피보나치 수5 | C++ (0) | 2022.08.04 |
---|---|
백준 온라인 저지 | 10872번 팩토리얼 | C++ (0) | 2022.08.04 |
백준 온라인 저지 | 2178번 미로 탐색 | C++ (0) | 2022.03.08 |
백준 온라인 저지 | 1926번 그림 | C++ (0) | 2022.03.08 |
백준 온라인 저지 | 5397번 키로거 | C++ (0) | 2022.02.27 |
댓글