< 프로그래머스 C++ > 모의고사

2026. 5. 7. 09:33Programmers

문제 설명

문제 설명

 

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다.

1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...
3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...

1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요.

제한 조건
  • 시험은 최대 10,000 문제로 구성되어있습니다.
  • 문제의 정답은 1, 2, 3, 4, 5중 하나입니다.
  • 가장 높은 점수를 받은 사람이 여럿일 경우, return하는 값을 오름차순 정렬해주세요.
입출력 예
answers                                                                                                     return
[1,2,3,4,5] [1]
[1,3,2,4,2] [1,2,3]
입출력 예 설명

 

입출력 예 #1

  • 수포자 1은 모든 문제를 맞혔습니다.
  • 수포자 2는 모든 문제를 틀렸습니다.
  • 수포자 3은 모든 문제를 틀렸습니다.

따라서 가장 문제를 많이 맞힌 사람은 수포자 1입니다.

 

입출력 예 #2

  • 모든 사람이 2문제씩을 맞췄습니다.

문제 해석

이 문제의 포인트는 두 가지이다.

  1. 세 사람의 답안은 정해진 패턴의 무한 반복
  2. 각 사람의 답을 정답과 비교해서 점수를 계산한 뒤, 최고점과 같은 점수를 가진 사람을 모두 찾기

패턴 분석

각 수포자의 답을 자세히 보면 일정 길이로 반복된다.

 

수포자 패턴 패턴 길이

1번 1, 2, 3, 4, 5 5
2번 2, 1, 2, 3, 2, 4, 2, 5 8
3번 3, 3, 1, 1, 2, 2, 4, 4, 5, 5 10

무한 반복 구현하기

문제는 시험이 최대 10,000문제까지 나올 수 있다는 것이다. 패턴을 10,000개 복사해서 만들 수도 없고, 만들 필요도 없다.

여기서 나머지 연산자를 활용한다.

i번째 문제에서 1번 수포자가 찍은 답은 user1[i % 5]로 구할 수 있다. i가 5를 넘어가면 i % 5는 다시 0부터 시작하므로 패턴이 자연스럽게 반복된다.

i = 0  →  i % 5 = 0  →  user1[0] = 1
i = 1  →  i % 5 = 1  →  user1[1] = 2
i = 5  →  i % 5 = 0  →  user1[0] = 1  (다시 시작!)
i = 6  →  i % 5 = 1  →  user1[1] = 2

사용할 도구

  • 나머지 연산자 % - 패턴 무한 반복
  • max 함수 - 세 값 중 최댓값 찾기

문제 풀이

#include <string>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> solution(vector<int> answers) {
    vector<int> answer;
    vector<int> user1 = {1, 2, 3, 4, 5};
    vector<int> user2 = {2, 1, 2, 3, 2, 4, 2, 5};
    vector<int> user3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
    
    int score1 = 0, score2 = 0, score3 = 0;
    
    for(int i = 0; i < answers.size(); ++i)
    {
        if(user1[i % 5] == answers[i]) score1++;
        if(user2[i % 8] == answers[i]) score2++;
        if(user3[i % 10] == answers[i]) score3++;
    }
    
    int max_score = max({score1, score2, score3});
    
    if(score1 == max_score) answer.push_back(1);
    if(score2 == max_score) answer.push_back(2);
    if(score3 == max_score) answer.push_back(3);
    
    return answer;
}

핵심 포인트

1. 나머지 연산자로 패턴 반복

user1[i % 5]

% 연산자는 나눗셈의 나머지를 반환한다. 이걸 배열 인덱스에 사용하면 순환 인덱스효과가 생긴다.

// 나머지 연산이 만드는 인덱스 시퀀스
i:        0 1 2 3 4 5 6 7 8 9 ...
i % 5:    0 1 2 3 4 0 1 2 3 4 ...   ← 5마다 다시 0부터

 

2. max 함수로 세 값 중 최댓값 찾기

int max_score = max({score1, score2, score3});

 

 

 

3. 동점자 처리 — 오름차순 보장

if(score1 == max_score) answer.push_back(1);
if(score2 == max_score) answer.push_back(2);
if(score3 == max_score) answer.push_back(3);

동점자가 여럿일 경우 결과를 오름차순으로 반환해야 한다. 이걸 따로 정렬하지 않고, 1번부터 순서대로 체크하는 방식으로 자연스럽게 오름차순을 만들었다.

 

만약 점수가 [10, 10, 10]이라면:

  1. score1 == max_score → answer에 1 추가 → [1]
  2. score2 == max_score → answer에 2 추가 → [1, 2]
  3. score3 == max_score → answer에 3 추가 → [1, 2, 3]

4. 패턴 길이를 코드에 박아넣기

if(user1[i % 5] == answers[i]) score1++;

여기서 5, 8, 10은 각각 패턴 길이를 직접 적은 것이다. 하드코딩이라 살짝 아쉬워 보이지만, 이번 문제처럼 패턴이 고정되어 있는 경우에는 충분하다.

 

좀 더 깔끔하게 쓰고 싶다면 user1.size()를 사용할 수도 있다.

if(user1[i % user1.size()] == answers[i]) score1++;

이렇게 하면 패턴 길이가 바뀌어도 코드를 수정할 필요가 없어진다.


정리

이 문제의 핵심은 반복되는 패턴을 나머지 연산으로 처리하는 것이다.

  • 패턴 배열을 한 번만 만들고, i % 패턴길이로 무한 반복 효과 구현
  • max({a, b, c}) 형태로 세 값 중 최댓값을 비교
  • 동점자 처리는 1번부터 순서대로 체크해서 자동으로 오름차순 보장