문제

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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하는 값을 오름차순 정렬해주세요.

나의 코드

 

import java.util.*;

public class MockTest {
	public static int[] solution(int[] answers) {
        
        int[] test11 = {1, 2, 3, 4, 5};
        int[] test22 = {2, 1, 2, 3, 2, 4, 2, 5};
        int[] test33 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
        Queue<Integer> test1 = new LinkedList<>();
        Queue<Integer> test2 = new LinkedList<>();
        Queue<Integer> test3 = new LinkedList<>();
        for(int go : test11) test1.offer(go); 
        for(int go : test22) test2.offer(go);
        for(int go : test33) test3.offer(go);
        
        HashMap<Integer, Integer> hash = new HashMap<>();
        hash.put(1, 0);
        hash.put(2, 0);
        hash.put(3, 0);
        for(int i=0; i<answers.length; i++) {
        	int move1 = test1.poll();
        	int move2 = test2.poll();
        	int move3 = test3.poll();
        	if(answers[i] == move1) {
        		hash.put(1, hash.getOrDefault(1, 0)+1);
        	}
        	if(answers[i] == move2) {
        		hash.put(2, hash.getOrDefault(2, 0)+1);
        	}
        	if(answers[i] == move3) {
        		hash.put(3, hash.getOrDefault(3, 0)+1);
        	}
        	test1.offer(move1);
        	test2.offer(move2);
        	test3.offer(move3);
        }
        List<Integer> list = new ArrayList<>(hash.keySet());
        Collections.sort(list, (o1, o2) -> (hash.get(o2).compareTo(hash.get(o1))));
        int master = hash.get(list.get(0));
        for(int key : list) {
        	if(hash.get(key)!= master) {
        		hash.remove(key);
        	}
        }
        int[] answer = new int[hash.size()];
        int index = 0;
        for(int ans : hash.keySet()) {
        	answer[index] = ans;
        	index ++;
        }
        return answer;
    }
}

나의 풀이

우선 완전 탐색이란 '무식하게 푼다' 라는 개념으로 brute-force 라고도 한다. 이는 컴퓨터의 빠른 계산 능력을 이용해 가능한 경우의 수를 일일이 나열하면서 답을 찾는 방법을 의미한다. 곧 가능한 방법을 전부 만들어보는 알고리즘이라고 할 수 있다

1. 문제에 주어져 있는 세명의 정답을 찍는 패턴이다. 그 패턴들을 test1, test2, test3 의 배열에 다 저장해 놓는다.

2. test1,2,3 에 있는 패턴들을 Queue에 각자 저장한다. (이유는 패턴이 반복되는 것이므로 순서대로 poll 한 후 offer해주기 위해)

3. HashMap<Integer,Integer> hash 를 선언해서 우선 세명의 키 값과 각자 0 의 value 를 준다.

4. for문을 통해 인자로 넘어온 answers 의 길이만큼 돌린다.

5. test1,2,3 큐의 첫 번째 값을 poll하여 move1,2,3에 저장한다.

6. 만약 answers[i]의 값과 move1,2,3 의 값이 같을 때 getOrDefault를 사용하여 해당 key에 1씩 더해준다.

7. 세 개의 if문을 다 거쳤다면 poll한 값을 다시 offer시켜줘서 맨 뒤로 넣어준다. (같은 패턴으로 계속 찍을 것이기 때문)

8. hash의 keySet을 가지고 있을 ArrayList를 하나 선언한다.

9. Collections.sort를 이용해 list에 들어있는 key값에 해당하는 value를 내림차순 정렬시킨다.

10. int master(가장 많이 맞춘 사람의 맞춘 개수)에는 정렬된 내림차순 정렬된 list의 키값에 해당하는 value를 저장한다.

11. list를 for문 돌려 만약 master와 그다음으로 정렬된 사람들의 value가 다르다면 해당 key를 hash에서 삭제한다.

12. 정답이 들어갈 answer[]에는 hash의 사이즈만큼 할당한다.

13. int index는 answer의 순차적인 index를 위해 선언된 것.

14. for문을 통해 hash에 들어있는 keySet을 돌려 answer[index]에 저장한다. 그리고 index++

15. 정답 return

+ Recent posts