코딩 테스트 공부/프로그래머스

[ JAVA ] 프로그래머스 - 양궁대회

따갓 2022. 6. 15. 01:30

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

 

코딩테스트 연습 - 양궁대회

문제 설명 카카오배 양궁대회가 열렸습니다. 라이언은 저번 카카오배 양궁대회 우승자이고 이번 대회에도 결승전까지 올라왔습니다. 결승전 상대는 어피치입니다. 카카오배 양궁대회 운영위원

programmers.co.kr

 

[ 풀이 ]

먼저 내가 생각한 풀이는 다음과 같았다.

 

1. 라이언이 적중한 화살들을 기록하는 배열 RYAN[] 을 생성한다. 이 때 n 개의 적중한 화살들의 경우의 수는 " 중복조합 " 을 이용해 구한다. 중복조합을 뽑는 함수는 백트래킹을 이용해 구현하였다. 그리고 RYAN[] 배열들을 저장하는 list를 생성한다.

 

2. RYAN[] 을 생성하였다면 이후에 어피치가 적중한 화살들의 기록 APEACH[] 배열과 비교해본다. APEACH_score , RYAN_score 는 각각 어피치와 라이언의 총 점수가 된다.

  • RYAN[i] > APEACH[i] 일 경우 : RYAN_score += ( 10 - i )
  • RYAN[i] <= APEACH[i] 일 경우 : APEACH_score += ( 10 - i )
  • 둘다 0개를 맞춘 경우 : 둘 다 점수를 얻지 못하므로 continue;

3. 어피치의 총 점수보다 라이언의 총 점수가 더 클 경우( RYAN_score > APEACH_score ) 다음 케이스에 대해 비교해본다. 이 때 ( 라이언 총 점수 - 어피치 총 점수 )  값을 max 값과 비교해야 한다.

  • ( 라이언 총 점수 - 어피치 총 점수 ) > max 일 경우 >>  max 값을 ( 라이언 총 점수 - 어피치 총 점수 ) 값으로 갱신한 뒤, list 도 모두 갱신시킨다. 그리고 갱신된 list에 RYAN[] 배열을 새로 추가한다.
  • ( 라이언 총 점수 - 어피치 총 점수 ) ==  max 일 경우 >> list에 RYAN[] 배열을 추가한다.

4. 가능한 모든 RYAN[] 배열이 list에 저장이 되었다면, 문제의 조건에 따라 " 점수가 낮은 화살이 많은 순대로" list를 정렬해야한다. 

 

5. 정렬 후 list.get(0) 하면 정답이 된다.

 

문제는 위의 시나리오대로 코드를 구현하기에 나의 구현 능력이 부족하여 중간중간마다 막히는 구간이 생겼다.. 그래서 구글링을 해봤는데, 마침 나와 거의 비슷하게 풀이를 생각하신 분을 발견하였다!

https://rotomoo.tistory.com/51

 

[프로그래머스] 양궁대회 Level2 (자바,java)

- 풀이 백트래킹으로 모든 경우의수를 구해준다. 여기서 경우의수는 중복 조합으로 경우의수를 체크해야 시간초과가 안걸린다. 문제에 라이언이 가장 큰 점수 차이로 우승할 수 있는 방법이 여

rotomoo.tistory.com

위 블로그 내용을 참고하여 코드를 완전히 구현 할 수 있었고 결과는 테스트 통과!

 

[ 중복 조합 뽑는 함수 ] 

static void findCase( int count , int s , int n ){
    if( count == n ) {	// n : 총 화살 개수 , count : 쐈던 개수 ( 초기값 : 0 )
        isRYAN_WIN();    // 라이언이 이겼는지 판별하는 함수
        return;
    }
    for (int i = s; i < 11; i++) {
        RYAN[i]++;
        findCase( count + 1 , i , n );  
        RYAN[i]--;
    }
}

[ isRYAN_WIN() ]

static void isRYAN_WIN(){
    int APEACH_score = 0;
    int RYAN_score = 0;
    for( int i = 0 ; i < RYAN.length ; i++ ){
        if( APEACH[i] == 0 && RYAN[i] == 0 ) continue;
        if( APEACH[i] >= RYAN[i] ) APEACH_score += 10 - i ;
        else RYAN_score += 10 - i ;
    }
    if( RYAN_score > APEACH_score ){
        if( RYAN_score - APEACH_score > max ){	// 라이언과 어피치의 점수차가 최대인지 확인
            max = RYAN_score - APEACH_score;
            list.clear();
            list.add( RYAN.clone() );
        } else if ( RYAN_score - APEACH_score == max ) list.add( RYAN.clone() );            
    }
}

[ 전체 코드 ] 

import java.util.*;

class Solution {
    static ArrayList<int[]> list = new ArrayList<>();
    static int[] RYAN;
    static int[] APEACH;    
    static int max = Integer.MIN_VALUE;
    public int[] solution(int n, int[] info) {        
        int sum = 0;         
        RYAN = new int[ info.length ];
        APEACH = info.clone();
        findCase( 0 , 0 , n );
        
        if( list.isEmpty() ) return new int[]{-1};
        
        // 문제의 조건에 따라 정렬
        Collections.sort(list, (o1, o2) -> {	
            for (int i = 10; i >= 0; i--) {
                if (o1[i] != o2[i]) return o2[i] - o1[i];
            }
            return 0;
        });
        return list.get(0);
    }
    static void findCase( int count , int s , int n ){
        if( count == n ) {
            isRYAN_WIN();    
            return;
        }
        for (int i = s; i < 11; i++) {
            RYAN[i]++;
            findCase( count + 1 , i , n );  
            RYAN[i]--;
        }
    }    
    static void isRYAN_WIN(){
        int APEACH_score = 0;
        int RYAN_score = 0;
        for( int i = 0 ; i < RYAN.length ; i++ ){
            if( APEACH[i] == 0 && RYAN[i] == 0 ) continue;
            if( APEACH[i] >= RYAN[i] ) APEACH_score += 10 - i ;
            else RYAN_score += 10 - i ;
        }
        if( RYAN_score > APEACH_score ){
            if( RYAN_score - APEACH_score > max ){
                max = RYAN_score - APEACH_score;
                list.clear();
                list.add( RYAN.clone() );
            } else if ( RYAN_score - APEACH_score == max ) list.add( RYAN.clone() );            
        }
    }
}