
알고리즘을 학습할 수록 느끼는 점이지만, 나는 정말 문제 해석이 너무 어렵다.
잘 알아듣다가도 이해가 안되는 부분이 생기면 거기서 막혀버린다. 이번 숙제도 그랬다. 난이도 하인데 왜 바로바로 못 풀겠지? 문제 해석하는 데에만 시간이 많이 들었다.
최대한 잘 정리해보려고 하는데 이번에도 막히는 부분이 생겼다.
/**음악 테스트 응시자의 패턴
* 시험 문제의 정답이순서대로 들어있는 배열 answer가 주어졌을 때,
* 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return하는 함수를 작성하기
* 응시자 3명
* (1) 1번 응시자의 패턴: [도, 레, 미, 파]
* 4개의 음계를 순차적으로 반복
* ex) 도,레,미,파,도,레,미,파,도,레,...
* (2) 2번 응시자의 패턴: [레, 레, 파, 파, 도, 도]
* 6개의 음계를 순차적으로 반복
* ex) 레,레,파,파,도,도,레,레,파,파,...
* (3) 3번 응시자의 패턴: [미, 파, 미, 도, 레, 도]
* 6개의 음계를 순차적으로 반복
* ex) 미,파,미,도,레,도,미,파,미,도,...
* 입력
* 배열 answer (ex. 도, 레, 미, 파, ... )
answer의 크기 N (0 ≤ N ≤ 5000)
answer의 값은 도, 레, 미, 파 중 하나
* 출력
* 가장 많은 문제를 맞힌 사람*/
그런데 문제의 제한사항이 2가지가 있다.
제한사항
시험은 최대 10,000 문제로 구성되어있습니다.
문제의 정답은 1, 2, 3, 4, 5중 하나입니다.
가장 높은 점수를 받은 사람이 여럿일 경우, return하는 값을 오름차순 정렬해주세요.
제한사항
시험은 최대 5,000 문제로 구성되어있습니다.
가장 높은 점수를 받은 사람이 여럿일 경우, return하는 값을 오름차순 정렬해주세요.
정답이 1, 2, 3, 4, 5 ??
오타이신거죠제발오타라고해주세요
이건일단 제쳐두고 뒤를 쭉쭉 읽었다.
→ 매니저 님께 바로 질문드리니 첫번째 제한사항으로 풀라고 딱 정해주셨다. 근데 막상 문제를 풀어보니 직접 배열을 입력하는 경우라 중요하지 않은 부분이었음...(물론 실제 프로그램을 만들게 된다면 중요함!!!)
여기서도 혼란2가 탄생한다.
해석 1. 입력받는 값은 개수 N 하나뿐이다.
이 경우 4가지 문자열 중 값을 랜덤하게 하나씩 가져와 배열로 만드는 과정이 필요하다.
해석 2. 문제의 개수 N도 입력받고 그 뒤에 answer도 입력받는다.
굳이요..?문제의 개수가 10,000개면 사용자가 10,000번 입력해야 하는데?
내가 너무 확대해석하는 것일 수도 있어서 제시된 예시 코드를 가져왔다.
public class Solution {
public int[] solution(String[] answers) {
int[] answer = {} ;
return answer;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Solution solution = new Solution();
// 문제 개수 입력
int N = sc.nextInt();
// 정답 배열 입력
String[] answers = new String[N];
for(int i = 0; i < N; i++) {
answers[i] = sc.next();
}
// 결과 출력
int[] result = solution.solution(answers);
StringBuilder sb = new StringBuilder();
for(int i = 0; i < result.length; i++) {
sb.append(result[i]);
if(i < result.length - 1) {
sb.append(" ");
}
}
System.out.println(sb.toString());
}
해석 2가 맞았다. 아직 테스트 단위라서 큰 정답 배열이 들어올 경우를 고려하지 않아도 되나보다.
정답 배열을 직접 입력받는 형태라면 문제가 쉽다. 바로 코딩 시작.
초기화
1) 입력된 N개의 answer 배열을 생성한다.
점수 계산 구현
2) answer 배열과 응시자들의 배열의 요소를 N개만큼 비교해간다.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Solution {
String[] tester1 = {"도", "레", "미", "파"};
String[] tester2 = {"레", "레", "파", "파", "도", "도"};
String[] tester3 = {"미", "파", "미", "도", "레", "도"};
public int[] solution(String[] answers) {
List<String[]> testers = new ArrayList<String[]>();
testers.add(tester1);
testers.add(tester2);
testers.add(tester3);
int[] score = new int[testers.size()]; //각 응시자의 점수 배열
ArrayList<Integer> pass = new ArrayList<>();
for (int i = 0; i < testers.size(); i++) {
for (int j = 0; j < answers.length; j++) {
if(testers.get(i)[j%testers.get(i).length].equals(answers[j]))
{score[i]++;}
}
}
int best = Math.max(Math.max(score[0], score[1]), score[2]); // 최고점수 best
for(int s = 1; s < score.length; s++) { //최고점을 가진 응시자 번호 추출
if(score[s-1]==best){ pass.add(s); }
}
int[] answer = new int[pass.size()];
for (int i = 0; i < pass.size(); i++) {
if(pass.get(i)==0){ continue; }
else answer[i] = pass.get(i);
}
return answer;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Solution solution = new Solution();
// 문제 개수 입력
int N = sc.nextInt();
// 정답 배열 입력
String[] answers = new String[N];
for (int i = 0; i < N; i++) {
answers[i] = sc.next();
}
// 결과 출력
int[] result = solution.solution(answers);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.length; i++) {
sb.append(result[i]);
if (i < result.length - 1) {
sb.append(" ");
}
}
System.out.println(sb.toString());
}
}
// 2.1. 모든 문제(answers 배열 길이)에 대해 반복 for(int i = 0; i < answers.length; i++) { // 2.2. 각 응시자별 점수 계산 // pattern[i % pattern.length]로 현재 답 확인하고 정답과 일치하면 점수 증가 if(answers[i].equals(pattern1[i % pattern1.length])) scores[0]++; // 1번 응시자 if(answers[i].equals(pattern2[i % pattern2.length])) scores[1]++; // 2번 응시자 if(answers[i].equals(pattern3[i % pattern3.length])) scores[2]++; // 3번 응시자 }
막상 다 풀고나니 왜 난이도가 '하'였는지 이해됐다. 역시 💩인지 된장인지 찍어먹어 봐야 아는 나답다.
수학 문제 풀듯이 매일 꾸준히 코딩 문제를 하나씩, 여러개씩 풀어보면서 알고리즘을 정복해봐야겠다.