포스트

프로그래머스 118666 - 성격 유형 검사하기 Lv.1

프로그래머스 118666 - 성격 유형 검사하기 Lv.1

출처: https://school.programmers.co.kr/learn/courses/30/lessons/118666

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// 프로그래머스 118666 - 성격 유형 검사하기 Lv.1
// https://school.programmers.co.kr/learn/courses/30/lessons/118666

// 문제 설명
// 4개 지표(RT, CF, JM, AN)로 16가지 성격 유형을 가린다.
// survey[i]의 첫 글자는 비동의 쪽, 둘째 글자는 동의 쪽에서 얻는 유형.
// choices[i]는 1~7 선택지. 1/7=3점, 2/6=2점, 3/5=1점, 4(모르겠음)=0점.
//   1,2,3(비동의) -> 첫 글자가 점수, 5,6,7(동의) -> 둘째 글자가 점수.
// 지표별로 점수가 높은 유형을 고르고, 동점이면 사전순 빠른 유형을 택한다.

// 제약 조건
// 1 <= survey 길이(n) <= 1,000
// survey 원소는 "RT","TR","FC","CF","MJ","JM","AN","NA" 중 하나
// 1 <= choices 원소 <= 7

// 접근 — 지표마다 부호 있는 점수 하나로 압축
// 4개 지표를 사전순으로 정렬해 lo="RCJA", hi="TFMN"로 둔다.
// 지표별 누적 점수를 양수면 lo 우세, 음수면 hi 우세로 관리하면
// 두 유형 점수를 따로 더해 비교할 필요가 없다.
// lo가 점수를 얻으면 +, hi가 얻으면 - 로 더하고,
// 마지막에 score >= 0 이면 lo 선택 -> 동점(0)이 사전순 lo로 자동 처리된다.
// 시간 O(n), 공간 O(1).

#include <string>
#include <vector>

using namespace std;

string solution(vector<string> survey, vector<int> choices)
{
    string answer = "";

    string lo = "RCJA";             // 각 지표의 사전순 앞 유형
    string hi = "TFMN";             // 각 지표의 사전순 뒤 유형
    int score[4] = {0, 0, 0, 0};    // 양수면 lo, 음수면 hi 우세 (0이면 사전순 lo)

    for (int i = 0; i < (int)survey.size(); i++)
    {
        int c = choices[i];
        char gain;                  // 점수를 얻는 유형
        int p;                      // 얻는 점수
        if (c < 4)      { gain = survey[i][0]; p = 4 - c; }  // 1~3(비동의): 첫 글자가 4-c점
        else if (c > 4) { gain = survey[i][1]; p = c - 4; }  // 5~7(동의): 둘째 글자가 c-4점
        else            { continue; }                        // 4(모르겠음): 점수 없음

        for (int k = 0; k < 4; k++)
        {
            if (gain == lo[k]) { score[k] += p; break; }
            if (gain == hi[k]) { score[k] -= p; break; }
        }
    }

    for (int k = 0; k < 4; k++)
        answer += (score[k] >= 0) ? lo[k] : hi[k];

    return answer;
}

정리

  • 4개 지표를 사전순으로 정렬lo="RCJA", hi="TFMN"로 두면 인덱스 k가 곧 지표 번호가 된다.
  • 지표마다 두 유형 점수를 따로 들지 않고 부호 있는 점수 하나로 압축한다. lo가 얻으면 +, hi가 얻으면 -.
  • 선택지 점수는 c<44-c(비동의·첫 글자), c>4c-4(동의·둘째 글자), c==4는 0점.
  • 마지막에 score >= 0이면 lo를 고르므로 동점(0)이 사전순 빠른 유형으로 자동 처리된다. 따로 분기할 필요가 없다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.