알고리즘 문제풀이/백준

[백준/BOJ] 8979번 올림픽 (C++)

노력의천재 2021. 9. 30. 01:22

https://www.acmicpc.net/problem/8979

 

8979번: 올림픽

입력의 첫 줄은 국가의 수 N(1 ≤ N ≤ 1,000)과 등수를 알고 싶은 국가 K(1 ≤ K ≤ N)가 빈칸을 사이에 두고 주어진다. 각 국가는 1부터 N 사이의 정수로 표현된다. 이후 N개의 각 줄에는 차례대로 각

www.acmicpc.net

각각의 메달의 수가 같은 경우 등수 처리를 잘해줘야 하는 문제이다. 예를들어 입력이 다음과 같다면, 등수는 다음과 같이 된다.

 

4 3

1 1 2 0 -> 1

2 0 1 0 -> 2

3 0 1 0 -> 2

4 0 0 1 -> 4

 

나는 각각의 메달의 개수를 문자열로 변환하고, 이것을 map의 key로 사용하였다. 해당 문자열을 key로 했을 때 value가 0이라면 유일한 순위이고, 0이 아니라면 똑같은 순위가 존재한다. 그리고 똑같은 등수가 몇개가 나오는지 개수를 세어서 현재 순위에서 개수를 더해 다음 순위를 구하는 방법으로 문제를 해결했다.

 

#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;

struct Medal {
	int num, g, s, b;
};

int cmp(Medal &x, Medal &y) {
	if(x.g == y.g) {
		if(x.s == y.s) {
			if(x.b == y.b) return x.num < y.num;	
			return x.b > y.b;
		}
		return x.s > y.s;
	}
	return x.g > y.g;
}

int main(void) {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	
	int n, k;
	vector<Medal> v;
	unordered_map<string, int> um;
	
	cin >> n >> k;
	for(int i = 0; i < n; i++) {
		int c, g, s, b;
		cin >> c >> g >> s >> b;
		v.push_back({ c, g, s, b });
	}
	
	sort(v.begin(), v.end(), cmp);
	
	int rank = 0, cnt = 1;
	vector<pair<int, int> > res;
	
	for(int i = 0; i < n; i++) {
		string str = to_string(v[i].g) + to_string(v[i].s) + to_string(v[i].b);
		if(um[str] == 0) {
			um[str] = v[i].num;
			res.push_back({ v[i].num, rank + cnt });
			rank += cnt;
			cnt = 1;
		} else {
			res.push_back({ v[i].num, rank });
			cnt++;
		}
	}
	 
	for(int i = 0; i < n; i++) {
		if(res[i].first == k) {
			cout << res[i].second;
			return 0;
		}
	}
}