티스토리 뷰
안녕하세요. 09LABS입니다.
오늘은 프로그래머스 연습문제 - 모의고사에 대한 해설입니다.
먼저 문제부터 보시죠.
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하는 값을 오름차순 정렬해주세요.
입출력 예
answersreturn
[1,2,3,4,5] | [1] |
[1,3,2,4,2] | [1,2,3] |
입출력 예 설명
입출력 예 #1
- 수포자 1은 모든 문제를 맞혔습니다.
- 수포자 2는 모든 문제를 틀렸습니다.
- 수포자 3은 모든 문제를 틀렸습니다.
따라서 가장 문제를 많이 맞힌 사람은 수포자 1입니다.
입출력 예 #2
- 모든 사람이 2문제씩을 맞췄습니다.
문제에서 주어진 조건을 정리해보면
1) 문제의 갯수가 주어지지 않았고
2) 인원은 총 3명이며 찍는 패턴은 일정하다
3) 정답은 모두 맞출수도 있으며 일부 또는 한명만 맞출수도 있다.
4) 정답을 맞춘 수포자의 번호를 오름차순으로 정렬하여 반환하라.
따라서 문제의 길이(갯수)는 무작위로 주어지며 10,000개의 테스트케이스에 대비해야한다는 것입니다.
주어지는 문제는 일정한 패턴이 주어진 것이 아니므로 전체 문제를 수포자들의 찍는 패턴에 대입해야 합니다.
이 문제를 풀면서 중요하게 생각한 것은 세가지 입니다.
1) 코드의 간결성
2) 메모리 최소화
3) 2중 반복문 (Big O가 Worst Case)인 경우가 발생하지 않도록 하는 것
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
|
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> solution(vector<int> answers) {
vector<int> answer;
vector<int> fst = {1,2,3,4,5}; // 수포자 1의 패턴
vector<int> snd = {2,1,2,3,2,4,2,5}; // 수포자 2의 패턴
vector<int> thd = {3,3,1,1,2,2,4,4,5,5}; // 수포자 3의 패턴
vector<int> score(3,0); // 정답을 맞춘 갯수
// 문제의 길이만큼 반복문 실행
for(int i = 0 ; i < answers.size() ; i++)
{
if(answers[i] == fst[i%5]) // 수포자 1의 정답 여부
score[0]++;
if(answers[i] == snd[i%8]) // 수포자 2의 정답 여부
score[1]++;
if(answers[i] == thd[i%10]) // 수포자 3의 정답 여부
score[2]++;
}
// 벡터에서 최대값을 추출
int max = *max_element(score.begin(), score.end());
for(int i = 0 ; i < 3 ; i++)
{
if(score[i] == max)
answer.push_back(i+1); // 최대값과 수포자 1,2,3의 점수와 같을 경우 answer 삽입
}
return answer;
}
|
cs |
10 ~ 12 : 수포자 1, 2, 3의 정답 패턴 벡터 생성
14 : 정답을 맞춘 갯수 벡터 초기화
17 ~ 25 : 정답을 맞춘 갯수를 계산하기 위한 반복문
수포자 1, 2, 3의 패턴에 따른 정답 여부 확인
28 : score 벡터에서 최대값 추출
30 ~ 34 : 최대값에 해당하는 수포자를 answer 벡터에 삽입
처음에 풀었던 코드는 문제의 길이만큼 수포자들의 정답 벡터를 늘려 비교하는 방식으로 코딩했지만
문제의 갯수가 많을 경우 주어진 메모리 크기를 초과하였다.
따라서 나머지를 구하는 연산자 %를 사용하여 인덱스를 계산, 정답을 확인하도록 변경하였다.
C++에선 C언어와 달리 벡터를 사용하는 것이 문제풀이에 있어 굉장히 편하게 코드를 만들 수 있다.
배열과 비슷해보이지만 스택과 유사하게 동작한다. 원하는 위치의 원소를 제거할 수도 있으며 맨 뒤에
원소를 추가, 삭제가 가능하고 assign이나 copy 함수를 사용하며 벡터 간 원소를 복사할 수 있다.
개인적인 의견으론 벡터는 포인터를 잘 알아야 쓰기 쉬운 느낌이다.
솔직히 해커랭크보다 프로그래머스가 난이도는 조-금 쉬운느낌?
'코딩하자 > 코딩테스트' 카테고리의 다른 글
[프로그래머스] Greedy - 체육복 (C++) (0) | 2021.01.10 |
---|---|
[Hackerrank Solution] 1. Solve Me First - (Warmup) (0) | 2020.11.01 |
- Total
- Today
- Yesterday
- 3D
- 하드웨어
- 프로젝트
- 아두이노
- fusion360
- 오픈소스 하드웨어
- 퓨전360
- Fusion 360
- 라즈베리파이
- 3d프린터
- 프린터
- 오픈소스
- DIY
- IOT
- ESP-IDF
- 자작
- SQLITE3
- 쏘카
- 3D 프린터
- 설계
- C언어
- 리눅스
- 3D Printer
- ESP
- esp32
- 코딩테스트
- Hypercube
- 해커랭크
- C++
- Arduino
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |