2025. 2. 6. 17:22ㆍPS (Program Solving)/BOJ (백준)
문제 설명
https://www.acmicpc.net/problem/23246
접근 방법 - 구조체를 활용한 정렬 응용문제
백준의 23246번 문제는 구조체 정렬을 활용하여 해결할 수 있는 문제이다.
해당 문제는, 각 선수의 고유 번호와 세 종목의 점수가 입력으로 주어질 때 금/은/동메달을 받을 선수의 고유 번호가 각각 어떻게 되는지를 구하여 출력해야 하는 문제이다.
이때, 순위를 결정짓는 기준은 아래와 같다.
- 3개의 점수를 모두 곱한 수가 낮은 선수가 더 높은 순위를 가진다.
- 곱산 결과가 동일한 경우엔, 3개의 점수를 모두 더한 수가 낮은 선수가 더 높은 순위를 가진다.
- 합산 결과도 동일한 경우엔, 선수의 고유 번호가 낮은 선수가 더 높은 순위를 가진다.
필자는 문제에 나타나있는 대로, 구조체(선수의 번호/곱산 결과/합산 결과)를 구성하고 이에 대한 정렬 함수를 작성하여 각 순위를 결정지었다.
정렬 문제를 여럿 풀어보았다면, 비교적 어렵지 않게 해결할 수 있는 문제로 예상이 된다.
이걸 반대로 뒤집어 말하면 익숙하지 않은 상태로 해결을 시도하기엔 다소 난이도가 있다고도 볼 수 있다.
자세한 설명을 아래에 기재해 놓으니, 혹여나 해당 문제를 해결하는 데에 어려움을 겪고 있다면 아래의 설명과 코드를 참고해 보길 바란다.
필자는 아래의 순서대로 코드를 작성하여 문제를 해결하였다.
코드의 실행 순서
1) 각 선수의 고유 번호와 순위 결정에 활용할 두 숫자를 저장할 구조체(medal)를 선언하도록 한다.
- num : 각 선수의 고유 번호
- hap : 세 종목 점수의 합산 결과
- gop : 세 종목 점수의 곱산 결과
2) 선수의 인원수(n)를 입력받는다.
그리고 각 선수의 정보를 저장하기 위하여, medal 구조체에 대한 배열(m)을 미리 선언해 둔다.
(n의 예상 최대 입력값인 100에 맞추어 구조체 배열의 크기를 설정해 주었다.)
3) n의 크기만큼, 반복문을 수행하여 아래의 연산을 취한다.
- 각 선수의 고유 번호(m[i].num)를 즉시 입력받아 저장한다.
- 세 종목의 점수(a, b, c)를 각각 입력받는다.
- a*b*c를 각 선수의 곱산 결과(m[i].gop)에, a+b+c를 각 선수의 합산 결과(m[i].hap)에 저장한다.
4) 별도로 정의한 compare() 함수와 sort() 내장 함수를 활용하여, m에 대하여 정렬을 수행한다.
(순위가 높을수록 m의 앞부분에 배정되게끔 하였으며, 위 지문에 있는 순위 결정 규칙을 기반으로 정렬을 수행하였다.)
- 곱산 결과(m.gop)에 대해 내림차순 정렬을 수행한다.
- 곱산 결과(m.gop)가 같다면, 합산 결과(m.hap)에 대해 내림차순 정렬을 수행한다.
- 합산 결과(m.hap)도 같다면, 선수의 고유 번호(m.num)에 대해 내림차순 정렬을 수행한다.
5) 위처럼 정렬을 수행하였다면, m[0]/m[1]/m[2]에 각각 1위/2위/3위에 해당하는 선수들이 배정되어 있을 것이다.
따라서, 위 3개의 num값을 순차적으로 공백으로 구분하며 정답으로 출력한다.
6) 정답을 출력하였다면, 프로그램 실행을 종료한다.
성공한 코드
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable: 4996)
#include <iostream>
#include <algorithm>
#define endl '\n'
using namespace std;
//백준 23246번 코드
struct medal {
int num;
int hap;
int gop;
};
bool compare(medal m1, medal m2) {
if (m1.gop == m2.gop) {
if (m1.hap == m2.hap) {
return m1.num < m2.num;
}
return m1.hap < m2.hap;
}
return m1.gop < m2.gop;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int n;
cin >> n;
medal m[101];
for (int i = 0; i < n; i++) {
cin >> m[i].num;
int a, b, c;
cin >> a >> b >> c;
m[i].hap = a + b + c;
m[i].gop = a * b * c;
}
sort(m, m + n, compare);
for (int i = 0; i < 3; i++) {
cout << m[i].num << " ";
}
cout << endl;
}
제출 결과
(2023.07.29 백준 23246번 문제 제출 결과)
'PS (Program Solving) > BOJ (백준)' 카테고리의 다른 글
[백준 BOJ] 21631번 Checkers (C++/cpp) (0) | 2025.02.02 |
---|---|
[백준 BOJ] 2210번 숫자판 점프 (C++/cpp) (0) | 2025.01.27 |
[백준 BOJ] 2476번 주사위 게임 (C++/cpp) (0) | 2025.01.26 |
[백준 BOJ] 10768번 특별한 날 (C++/cpp) (0) | 2025.01.01 |
[백준 BOJ] 1769번 3의 배수 (C++/cpp) (0) | 2024.12.29 |