2024. 2. 27. 15:31ㆍ알고리즘/문제풀이
3758번: KCPC
입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 테스트 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터의 첫 번째 줄에는
www.acmicpc.net
예제
2
3 4 3 5
1 1 30
2 3 30
1 2 40
1 2 20
3 1 70
4 4 1 10
1 1 50
2 1 20
1 1 80
3 1 0
1 2 20
2 2 10
4 3 0
2 1 0
2 2 100
1 4 20
ans :
1
2
정렬 기준이 3가지에 팀 번호까지 저장해둬야 한다. 정렬 기준은 다음과 같다.
- 최종 점수가 높을수록 등수가 낮다.
- 제출한 횟수가 낮을수록 등수가 낮다.
- 마지막 제출 시간이 낮을수록 등수가 낮다.
그리고 로그의 수 m이 최대 10000이므로 O(m log m)으로 풀어야 한다. 그럼 맵이나 정렬을 생각해 두고 구현에 들어갔다.
최종 점수를 계산하려면 과목별 점수를 계산해야 한다. 팀 코드와 문제 번호가 1~n, k까지 꽉 채워져있는지 랜덤으로 정해지는지 모르겠지만 일단 꽉 채워져 있다고 가정하고 풀었다. 각 팀의 과목별 점수와 제출한 횟수, 마지막 제출 시간을 먼저 다 따로 기록했다.
int score[101][101] = {}; // score[팀id][문제id] = 점수
int cnt[101] = {}; // 팀별 제출 회수
int idx[101] = {}; // 팀별 마지막 제출 시간
int n, k, t, m;
cin >> n >> k >> t >> m;
t--;
for (int i = 0; i < m; i++)
{
int tid, pid, score_;
cin >> tid >> pid >> score_;
tid--;
pid--;
score[tid][pid] = max(score[tid][pid], score_);
cnt[tid]++;
idx[tid] = i;
}
이제 이걸 정렬해주면 된다. 우선 아래 게시글을 참고해 보자!
[C++] 맵과 우선 순위 큐에서 정렬 기준 재정의하기
1. 맵에서 비교 연산자 재정의하기 #include #include // std::pair의 비교 연산자를 재정의하여 첫 번째 요소를 기준으로 정렬 struct PairCompare { bool operator()(const std::pair& a, const std::pair& b) const { return a.first
jun-n.tistory.com
이 게시글에서 필요한 내용만 한 줄 요약하자면 pair의 기본 정렬을 - 부호를 이용해서 사용하면 코드가 간단하다!
정렬 우선순위대로 벡터에 넣고 기본 sort를 쓰되, 내림차순으로 정렬할 데이터는 -를 붙이는 식으로 정렬했다.
vector<pair<pair<int, int>, pair<int, int>>> result;
// first = {최종 점수, cnt}, second = {마지막 제출 시간, tid}
for (int tid = 0; tid < n; tid++)
{
int sum = 0;
for (int j = 0; j < k; j++)
sum += score[tid][j];
result.push_back({{sum, -cnt[tid]}, {-idx[tid], tid}});
}
sort(result.begin(), result.end());
이렇게 하면 result 벡터는 최종 순위의 역순으로 정렬되어 있다!
/** 정렬 3758 KCPC **/
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
using namespace std;
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while (T--)
{
int score[101][101] = {}; // score[팀id][문제id] = 점수
int cnt[101] = {}; // 팀별 제출 회수
int idx[101] = {}; // 팀별 마지막 제출 시간
int n, k, t, m;
cin >> n >> k >> t >> m;
t--;
for (int i = 0; i < m; i++)
{
int tid, pid, score_;
cin >> tid >> pid >> score_;
tid--;
pid--;
score[tid][pid] = max(score[tid][pid], score_);
cnt[tid]++;
idx[tid] = i;
}
vector<pair<pair<int, int>, pair<int, int>>> result;
// first = {최종 점수, cnt}, second = {마지막 제출 시간, tid}
for (int tid = 0; tid < n; tid++)
{
int sum = 0;
for (int j = 0; j < k; j++)
sum += score[tid][j];
result.push_back({{sum, -cnt[tid]}, {-idx[tid], tid}});
}
sort(result.begin(), result.end());
for (int i = 0; i < n; i++)
if (result[i].second.second == t)
cout << n - i << '\n';
}
}
'알고리즘 > 문제풀이' 카테고리의 다른 글
[백준] 4803번: 트리 - 무방향 그래프에서 DFS로 사이클 찾기 (0) | 2024.07.02 |
---|---|
[백준] 1707번: 이분 그래프 C++ - BFS, 큐를 사용하여 이분 그래프 판단하기. (0) | 2024.06.28 |
[BOJ] C++ 20920: 영단어 암기는 괴로워 - 세 가지 기준의 우선순위 큐 (0) | 2024.02.18 |
[BOJ] C++ 13305: 주유소 - 우선순위 큐와 그리디 알고리즘 (1) | 2024.02.16 |
[BOJ] C++ 10431: 줄세우기 - 시뮬레이션은 문제를 잘 읽자! (1) | 2024.01.25 |