프로그래머스 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<4면4-c(비동의·첫 글자),c>4면c-4(동의·둘째 글자),c==4는 0점. - 마지막에
score >= 0이면lo를 고르므로 동점(0)이 사전순 빠른 유형으로 자동 처리된다. 따로 분기할 필요가 없다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.