본문 바로가기

CS/알고리즘 풀이

[ 프로그래머스 ] 모의고사 ( java )

[ 프로그래머스 ] 모의고사 ( 자바 ) 

3명의 학생이 시험에서 어떤 답을 규칙에 따라 찍는다. 정답 배열이 주어졌을때 가장 많이 맞춘 학생(들) 배열을 리턴하기 

 

https://programmers.co.kr/learn/courses/30/lessons/42840

 

코딩테스트 연습 - 모의고사 | 프로그래머스

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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,

programmers.co.kr

 

 

구조 

// 모든 답에 대해, i 

    // 답 == 1학생[ i % 1번길이 ]

        // cnt1++;

    // 답 == 2학생[ i % 2번길이 ]

        // cnt2++;

    // 답 == 3학생[ i % 3번길이 ]

      // cnt3++;

 

// 가장 많은 cnt인 학생들, int[] 담아서 리턴 

 

핵심 

1 반복하는 수열과 배열의 일치 

수열 [ a1, a2, a3 ]  , 배열 [ b1, b2, b3, b4, b5, b6 ,, ]

b1 b2 b3 b4 b5 b6
a1 a2 a3 a1 a2 a3
0 1 2 3 4 5

 

위 표처럼 확인하며 검사해야되는데, 검사는 실제 배열을 가리키는 인덱스를 시용하여 검사한다. 

수열은 반복적으로 매칭하는데 인덱스가 대신 반복해서? 가리킬 수 있다. 

'수열 인덱스 =  (배열인덱스 % 수열길이)' 로 하면 배열인덱스는 그냥 쭉 검사하는 동시에 수열 인덱스를 범위 초과없이 검사할 수 있게 된다. 

 

2 가장 많이 맞춘 학생(들)

1번은 대부분 동일한데 이부분에서 조금 다양함  

 

1 max, 가장 많이 맞춘 개수를 찾는다. 

2 일일히 모든 학생들과 max를 비교해서 max와 동일한 학생들 리턴 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//  최대 
int largest = Math.max(Math.max(cnt1, cnt2), cnt3);
ArrayList<Integer> ans = new ArrayList<Integer>();
 
// 최대와 같은 애들 추가 
if(cnt1 == largest) {
    ans.add(1);
}
if(cnt2 == largest) {
    ans.add(2);
}
if(cnt3 == largest) {
    ans.add(3);
}
// int[] 배열로 만들어서 리턴 
int[] ans2 = new int[ans.size()];
for(int i = 0 ; i < ans.size() ; i++) {
    ans2[i] = ans.get(i);
}
 
 
cs

또는

굳이 arraylist 객체 생성은 안해도 되지만 실수할 확률이 좀 될듯.

 

1
2
3
4
5
6
7
8
9
10
11
//  최대 
int largest = Math.max(Math.max(cnt1, cnt2), cnt3);
 
// arraylist없이 바로 답 생성 후 리턴 
// 최대와 같은 애들 추가 
 if(max == arr[0&& max == arr[1&& max == arr[2]) return new int[]{1,2,3};
else if(max == arr[0&& max == arr[1]) return new int[]{1,2};
else if(max == arr[0&& max == arr[2]) return new int[]{1,3};
else if(max == arr[1&& max == arr[2]) return new int[]{2,3};
else if(max == arr[0]) return new int[]{1};
else if(max == arr[1]) return new int[]{2};
cs

 

2 소팅 

이차원 배열 소팅, 제일 먼저 맞은 개수를 기준으로 소팅한다. 하지만 같다면, 값이 낮은 사람을 기준으로 소팅. 그리고 답 계산

 

 

 

최종 코드 

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
import java.util.*;
class Solution {
    public int[] solution(int[] answers) {
      
        int[] p1 = {1,2,3,4,5};
        int[] p2 = {2,1,2,3,2,4,2,5};
        int[] p3 = {3,3,1,1,2,2,4,4,5,5};
        int cnt1= 0, cnt2=0, cnt3=0;
        
        for(int i = 0 ; i < answers.length ; i++) {
            if(answers[i] == p1[i%p1.length]) {
                cnt1++;
            }
            if(answers[i] == p2[i%p2.length]) {
                cnt2++;
            }
            if(answers[i] == p3[i%p3.length]) {
                cnt3++;
            }
        }
        
        int largest = Math.max(Math.max(cnt1, cnt2), cnt3);
        ArrayList<Integer> ans = new ArrayList<Integer>();
        if(cnt1 == largest) {
            ans.add(1);
        }
        if(cnt2 == largest) {
            ans.add(2);
        }
        if(cnt3 == largest) {
            ans.add(3);
        }
        int[] ans2 = new int[ans.size()];
        for(int i = 0 ; i < ans.size() ; i++) {
            ans2[i] = ans.get(i);
        }
 
        return ans2;
    }
}
cs