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

2023. 9. 30. 00:01PS (Program Solving)/BOJ (백준)

문제 설명

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

 

8979번: 올림픽

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

www.acmicpc.net

백준 BOJ 8979번 올림픽 문제 사진1
백준 BOJ 8979번 올림픽 문제 사진2

 

접근 방법 - 구조체에 대한 정렬 응용문제

백준의 8979번 문제는 구조체 정렬에 있어 다소 심화적인 부분을 다루고 있는 문제이다.

해당 문제는, 금/은/동메달의 개수에 기준을 두어 특정 나라의 등수를 출력해야 하는 문제이다.

이때 필자는 개인적으로, 공동 순위의 개념이 포함되어 있음을 알리며 이 점에 대해 주의할 필요가 있다고 본다.

이걸 어떻게 고려하며 코드를 작성할지 고민하다가 작년에 드롭하였었기 때문이다...

이 외의 개념은 주로 구조체 응용과 구조체에 대한 정렬 함수 구현인데, 입문자인 경우엔 아래를 잘 참고해 볼 필요가 있어 보인다.

sort() 함수 사용 및 구조체의 개념을 잘 알고 있다면, 문제 해결에 대한 접근은 그리 어렵지 않았을 것이라 예상된다.

다만 해당 문제를 해결하는 데에 어려움을 겪고 있다면, 아래의 설명 및 코드를 참고해 보길 바란다.

필자는 아래의 순서대로 코드를 작성하여 문제를 해결하였다.

 

코드의 실행 순서

1) 각 나라의 번호(num) 및 3가지의 메달 정보(gold, silver, bronze)를 원활히 저장하기 위해, medal이라는 구조체를 임의로 정의한다.

구조체를 정의하였다면, 전역 변수로 medal 타입의 배열 m을 선언한다.

 

2) 국가의 수(n)와 등수가 궁금한 나라의 번호(k)를 입력받도록 한다.

뒤이어, n의 크기만큼 배열 m에 들어갈 값들을 순차적으로 입력받는다.

 

3) sort() 함수를 사용하여, 배열 m에 대해 정렬을 수행한다.

이때 문제의 조건을 반영하며 정렬을 수행하도록, 아래의 규칙을 compare 함수로 정의하도록 한다.

- gold >> silver >> bronze 순으로 "내림차순" 정렬을 수행한다.
- gold 값이 같다면 silver의 값을 비교, silver 값이 같다면 bronze의 값을 비교하는 식으로 진행한다.
(gold, silver, bronze 값 모두 같은 경우는 공동 순위로 책정되기 때문에, 이 경우에 대해선 정렬을 별도로 하지 않도록 한다.)

 

4) 순위를 카운트할 변수 rate를 선언한다.

 

5) i를 0부터 n-1까지 하여, 반복문을 수행하며 아래의 연산을 수행한다.

- 만일 i의 값이 0이라면, 현재 i에 1을 더한 값을 rate에 저장하도록 한다.

- 배열 m에 대해 i번째 메달 정보와 i-1번째 메달 정보가 동일하지 않은 경우에도, 순위에 변동이 있어야 하므로 현재 i에 1을 더한 값을 rate에 저장하도록 한다.

(만일 i번째와 i-1번째 메달 정보가 동일하다면, 같은 순위로 책정되어야 하기 때문에 별도의 연산을 취하지 않는다.)

- 만약 i번째 나라의 번호가 k와 동일하다면, 해당 나라의 순위를 출력하면 된다.

따라서, 최종적으로 저장된 rate의 값을 출력한 뒤, 즉시 실행 종료한다.

 

6) 5)에서 return 0;을 만나는 즉시, 실행 종료한다.

반응형

 

성공한 코드

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable: 4996)
#include <iostream>
#include <algorithm>
#define endl '\n'
using namespace std;

//백준 8979번 코드
struct medal {
	int num;
	int gold;
	int silver;
	int bronze;
};

bool compare(medal m1, medal m2) {
	if (m1.gold == m2.gold) {
		if (m1.silver == m2.silver) {
			return m1.bronze > m2.bronze;
		}
		return m1.silver > m2.silver;
	}
	return m1.gold > m2.gold;
}

medal m[1001];
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);   cout.tie(NULL);

	int n, k;
	cin >> n >> k;
	for (int i = 0; i < n; i++) {
		cin >> m[i].num >> m[i].gold >> m[i].silver >> m[i].bronze;
	}
	sort(m, m + n, compare);

	int rate;
	for (int i = 0; i < n; i++) {
		if (i == 0 || !(m[i].gold == m[i - 1].gold && m[i].silver == m[i - 1].silver && m[i].bronze == m[i - 1].bronze)) {
			rate = i + 1;
		}

		if (m[i].num == k) {
			cout << rate << endl;
			return 0;
		}
	}
}

 

제출 결과

백준 BOJ 8979번 올림픽 문제 C++ 제출 결과

(2023.07.26 백준 8979번 문제 제출 결과)

반응형