Codeing Test Study -3 완전 탐색

김민진·2021년 12월 20일
0

알고리즘

목록 보기
4/4

문제 설명
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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하는 값을 오름차순 정렬해주세요.
입출력 예
answers return
[1,2,3,4,5][1]
[1,3,2,4,2][1,2,3]
입출력 예 설명
입출력 예 #1

수포자 1은 모든 문제를 맞혔습니다.
수포자 2는 모든 문제를 틀렸습니다.
수포자 3은 모든 문제를 틀렸습니다.
따라서 가장 문제를 많이 맞힌 사람은 수포자 1입니다.

입출력 예 #2

모든 사람이 2문제씩을 맞췄습니다.

여기까지 문제이다.

나는 처음에 해당 문제를 잘못 이해했다.
1번,2번,3번 수포자가 찍는 방식만보고
수포자가 찍는방식조차 랜덤인건가? 싶었다..

그래서 수포자가 찍는방법과 답안지 2개를 받아야할거 같은데
매개변수는 answers 하나뿐이 없다.. 답안지만 들어와서

이걸 어떻게 푸는거지??하고 한참을 생각하다가 구글링을 해보니까 ...
수포자1,2,3 이라고 이미 주어진거였다 ㅜㅜㅜ

 public static int[] solution(int[] answers) {
        // answers 정답이 들어 있음
        int[] results = new int[3]; 답의 순위를 정하는곳
        int[] personRights = new int[3]; 각각의 수포자가 맞은 정답 수 
        int[] person = {1,2,3,4,5}; 수포자 1
        int[] person1 = {2,1,2,3,2,4,2,5}; 수포자 2
        int[] person2 = {3,3,1,1,2,2,4,4,5,5};수포자 3

person[i%person.length] 를 통해서 각각이 가진 배열의 수만큼 돌 수 있엇다.
0/5 = 0 0/8 = 0
1/5 = 1 1/8 = 1
2/5 = 2 2/8 = 2
3/5 = 3 3/8 = 3
4/5 = 4 4/8 = 4 ...
나눈뒤의 나머지 값을 적용하는 방식이다. 
        for(int i=0;i<answers.length;i++){
            if(person[i%person.length]==answers[i]){
                personRights[0]++;
            } if(person1[i%person1.length]==answers[i]){
                personRights[1]++;
            } if(person2[i%person2.length]==answers[i]){
                personRights[2]++;
            }
        }
		큰 값이 맨 앞으로 가는것으로 생각했다.
        for(int i=0;i<personRights.length;i++){
            if(i==0){
                results[i]=personRights[i];
                continue;
            }
            if(results[i-1]<personRights[i]){
                int temp = results[i-1];
                results[i-1] = personRights[i];
                results[i] = temp;
            }
        }


        return answer;
    }

결과는..
1,2,3,4,5
1,3,2,4,2
를 했을때

처음에는 5,0,0
그 다음에는 2,2,0이 나왔다.

답과 예시의 답을 잘 살펴보니 많이 달랐다.

첫 답은 1
두번째 답은 1,2,3 이였다.

애초에 문제자체를 이해하지 못해서 답이 엉망진창이였다.

문제에서 요구하는 것은

가장 많은 점수를 획득한 사람과
동점이라면 오름차순으로 정렬해서 답을 제출해야 하는것이였다.

                int max = Math.max(personRights[0],Math.max(personRights[1],personRights[2]));
                
                max 는 (a>=b) ? a:b
                a가 b보다 크거나 같으면 a 그렇지 않으면 b를 뱉어낸다.
                max에 적용된 것을 해석해보면
                personrights[0]이 a 이고
                Math.max(personrights[1],personRights[3]) 이 b에 해당하는 부분이다.
                b를 또 나누자면 
                personRights[1]과 personRights[3]중 큰 값을 다시 personRights[0]과 비교하는 것이다.
                
                결국 제일 큰 값이 나오게 된다.


        List<Integer> resultList = new ArrayList<>();

resultList 를 List로 선언한 이유는 아직 동점자가 몇명인지 모르기 때문이다.
동점자가 몇명인지 구하자면 또다시 for문을 써야하는데.. 사실 for를 쓰는것보다 무언가 선언하는게 나은방법 같아 보였다.(다른 이들도 사실 모두 이와같이 풀었더라..)

아래의 코드는 결국
동점자가 있다면 오름차순으로 정렬하는것까지가 사실 자동으로 되어지는 방법이다.
정말..좋네
        if(max == personRights[0]){
            resultList.add(1);
        }
        if(max == personRights[1]){
            resultList.add(2);
        }
        if(max == personRights[2]){
            resultList.add(3);
        }

해당 방법을 통해 동점자가 몇명인지 resultList.size()로 알 수 있다.
answer를 동점자 만큼 선언한뒤
동점자를 오름차순으로 넣어주면 된다.

        int[] answer = new int[resultList.size()];
        for(int i=0;i< resultList.size();i++){
            answer[i]=resultList.get(i);
        }

한번은 해답을 보고 이런식으로 정리한뒤 다음에 다시 한번 풀어보는 과정을 해봐야 겠다.

profile
dart,c#,java 개발자! 잡다하게 해서 문제될게 없다!

0개의 댓글