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() );
}
}
}'코딩 테스트 공부 > 프로그래머스' 카테고리의 다른 글
| [ JAVA ] 프로그래머스 - 쿼드압축 후 개수 세기 (0) | 2022.06.17 |
|---|---|
| [ JAVA ] 프로그래머스 - k 진수에서 소수 개수 구하기 (0) | 2022.06.16 |
| [ JAVA ] 프로그래머스 - 줄 서는 방법 (0) | 2022.06.14 |
| [ JAVA ] 프로그래머스 - 입국 심사 (0) | 2022.06.11 |
| [ JAVA ] 프로그래머스 - 배달 (0) | 2022.06.11 |