-
[C++] BOJ 2456번: 나는 학급회장이다프로그래밍/알고리즘 PS 2024. 3. 29. 20:02
학교에서 진행하는 수업에서 공유받은 알고리즘 문제를 풀어보았다. 문제의 난이도는 브론즈 1으로, 쉬울 것으로 예상하고 문제를 풀었으나 예상보다 코드가 길어지고 3번째 제출에서야 '맞았습니다!!'가 출력되어 브론즈 1 난이도 치고는 어려웠다. 개인적으로는 실버 난이도가 조금 더 적절하다고 생각이 든다.
문제 링크
https://www.acmicpc.net/problem/2456
문제 분석
3명의 후보 중 가장 큰 점수를 받은 후보
가 단 한 명인 경우에는 문제가 단순해지지만, 여러 명인 경우에는 조건문을 통해 확인해야 하는 조건이 많아져 코드가 길어지는 문제이다. 이 문제에서 조건문을 유심히 처리해야 하는 내용은 아래에 작성된 문제의 조건이다.점수가 가장 큰 후보가 여러 명인 경우에는 3점을 더 많이 받은 후보를 회장으로 결정하고, 3점을 받은 횟수가 같은 경우에는 2점을 더 많이 받은 후보를 회장으로 결정한다. 그러나 3점과 2점을 받은 횟수가 모두 동일하면, 1점을 받은 횟수도 같을 수밖에 없어 회장을 결정하지 못하게 된다.
문제 풀이
int score_sum[4]; int main(void) { int N; cin >> N; while (N--) { for (int i = 1; i <= 3; i++) { int value; cin >> value; score_sum[i] += value; } } int max_index = 1; int max_score = score_sum[1]; // 최고 점수를 받은 후보와 최고 점수 계산 for (int i = 1; i <= 3; i++) { if (max_score < score_sum[i]) { max_score = score_sum[i]; max_index = i; } else if (max_score == score_sum[i]) { max_index = i; } } cout << max_index << " " << max_score << '\n'; return 0; }
먼저 위와 같이 입력을 받고, 각 후보 별로 입력받은 점수들의 합을 계산한다. 그리고 최고 점수를 받은 후보가 몇 번인지와, 최고 점수를 계산한다. 위와 같이 코드를 작성해주면
최고 점수를 받은 후보가 한 명인 경우
에 대해서는 적절한 결과를 출력하게 된다.else if (max_score == score_sum[i]) { max_index = i; }
이 때, 위와 같이
max_score
의 점수와score_sum[i]
의 점수가 같을 때max_index
의 값을 바꾸어주는 이유는 최고 점수를 받은 후보가 여러 명인 경우max_index
가 더 큰 번호의 후보를 가리키도록 하기 위함이다.이제 여기서
최고 점수를 받은 후보가 여러 명인 경우
까지 처리하기 위해 코드를 추가해주자.int added_score[4][4]; // added_score[점수][학생] while (N--) { for (int i = 1; i <= 3; i++) { int value; cin >> value; score_sum[i] += value; added_score[value][i] += 1; } }
먼저 각 후보가 3점, 2점, 1점을 몇 번 받았는지 확인하기 위해
added_score[value][i]
배열을 추가해준다. 그리고 입력을 받을 때 for문 내에서added_score[value][i]
값을 계산해준다.위의 방식대로 구현하면
added_score
배열을 통해 학생 후보가 특정 점수를 받은 횟수를 확인할 수 있다. 예를 들어added_score[3][1]
에 접근할 경우 1번째 학생이 3점을 받은 횟수를 읽어오게 된다.그리고 다음으로 3점을 더 많이 받은 사람을 후보로 정하고, 만약 3점의 횟수가 동일한 경우 2점을 많이 받은 사람을 후보로 정하고, 2점을 받은 횟수마저 같은 경우 후보가 없도록 하는 코드를 작성해주자.
for (int i = 1; i <= 3; i++) { if (max_index == 0) break; if (max_index == i) continue; if (score_sum[i] == max_score) { if (added_score[3][i] > added_score[3][max_index]) { max_index = i; } else if (added_score[3][i] == added_score[3][max_index]) { if (added_score[2][i] > added_score[2][max_index]) max_index = i; else if (added_score[2][i] == added_score[2][max_index]) max_index = 0; } } }
코드를 작성하면 다음과 같다. if 문이 여러 번 중첩된다.
전체 코드
위의 작업을 종합해 작성한 전체 코드는 다음과 같다.
#include <iostream> #include <vector> using namespace std; int score_sum[4]; int added_score[4][4]; // added_score[점수][학생] int main(void) { ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; while (N--) { for (int i = 1; i <= 3; i++) { int value; cin >> value; score_sum[i] += value; added_score[value][i] += 1; } } int max_index = 1; int max_score = score_sum[1]; for (int i = 1; i <= 3; i++) { if (max_score < score_sum[i]) { max_score = score_sum[i]; max_index = i; } else if (max_score == score_sum[i]) { max_index = i; } } for (int i = 1; i <= 3; i++) { if (max_index == 0) break; if (max_index == i) continue; if (score_sum[i] == max_score) { if (added_score[3][i] > added_score[3][max_index]) { max_index = i; } else if (added_score[3][i] == added_score[3][max_index]) { if (added_score[2][i] > added_score[2][max_index]) max_index = i; else if (added_score[2][i] == added_score[2][max_index]) max_index = 0; } } } cout << max_index << " " << max_score << '\n'; return 0; }
결과
'프로그래밍 > 알고리즘 PS' 카테고리의 다른 글
[C++] BOJ 9012번: 괄호 (0) 2024.04.01 [C++] BOJ 1546번: 평균 (0) 2024.04.01 [C++] BOJ 18870번: 좌표 압축 (0) 2024.03.28 [C++] BOJ 1032번: 명령 프롬프트 (0) 2024.03.28 [C++] BOJ 1748번: 수 이어 쓰기 1 (0) 2024.03.28