카카오 문제답게 지문이 길고 조건이 많은 편이어서 문제를 이해하는데 시간이 조금 걸렸다.
로직은 완전 탐색으로 모든 중복 조합을 만들고 점수를 계산해서 라이언이 이기는 경우 info2 배열을 반환한다.
먼저 라이언이 쏜 화살을 result 배열에 넣는다. 화살은 n번 쏠 수 있으므로 result 배열을 n으로 초기화한다.
그리고 중복 조합 메서드인 com을 호출한다.
예를 들어, n이 9라면 만들어진 조합은 {0,0,0,0,3,5,9,10,10}와 같이 만들어질 것이다.
이 배열의 값이 의미하는 것은 9번의 기회에서 0번째 과녁을 4번, 3번째 과녁 한번, 5번째 과녁 한번
9번째 과녁 한번, 10번째 과녁 2번을 맞췄다는 의미이다.
이것을 info 배열의 형식으로 바꾸면 0번째 과녁은 10점이므로 {4, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2}으로 바뀌게 된다.
그리고 배열을 돌면서 어피치의 info와 라이언의 info2를 비교해서 점수를 계산하면 된다.
모든 조합을 계산하면서 어피치와 라이언의 점수차가 가장 큰 경우 max에 저장되고 배열은 answer에 저장된다.
여기서 라이언이 가장 큰 점수 차이로 우승할 수 있는 방법이 여러 가지 일 경우
가장 낮은 점수를 더 많이 맞힌 경우를 return 하라는 조건이 있는데
if (dif > max) {
max = dif;
answer = info2;
}
return;
위 코드와 같이 dif의 값이 max보다 클 때에만 저장한다면 자연스럽게 조건을 만족하게 된다.
중복 조합이 만들어질 때 문제의 요구처럼 가장 낮은 점수를 더 많이 맞힌 경우의 조합이 먼저 만들어지기 때문이다.
예를 들어, 같은 29점 차이가 나는 {2,3,1,0,0,0,0,1,3,0,0}과 {2,1,0,2,0,0,0,2,3,0,0}이 만들어지지만 {2,1,0,2,0,0,0,2,3,0,0}인 조합이 먼저 만들어지고 나중에 만들어지는 {2,3,1,0,0,0,0,1,3,0,0}은 answer 배열에 저장되지 않는다.
마지막으로 max의 값이 0이라면 라이언이 이길 수 있는 방법이 없는 것이기 때문에 {-1}을 리턴하고
그게 아니라면 answer 배열을 리턴하면 된다.
최종 코드
import java.util.*;
class Solution {
static int max;
static int[] answer;
public int[] solution(int n, int[] info) {
// 중복 조합 메서드 호출
com(0, n, 0, info, new int[n]);
// max가 0이면 라이언이 이긴 조합이 없다는 것
answer = (max == 0) ? answer = new int[]{-1} : answer;
return answer;
}
// 증복 조합 메서드
static void com(int s, int n, int idx, int[] info, int[] result) {
// n발을 전부 다 쐈다면
if (idx == n) {
// 점수 계산 메서드 호출
cul(info, result);
return;
}
// 라이언이 쏜 과녁을 중복 조합으로 만들기
for (int i = s; i < 11; i++) {
result[idx] = i;
com(i, n, idx + 1, info, result);
}
}
// 점수를 계산하는 메서드
static void cul(int[] info, int[] result) {
int[] info2 = new int[11];
// 조합을 info와 같은 배열로 만들기
for (int i : result) {
info2[10 - i]++;
}
// 라이언과 어피치 점수를 저장하는 변수
int r = 0;
int a = 0;
for (int i = 0; i < info.length; i++) {
int score = 10 - i;
// 라이언의 점수가 더 크다면
if (info2[i] > info[i]) {
r += score;
// 어피치의 점수가 더 크다면
} else if (info2[i] < info[i]) {
a += score;
// 어피치가 과녁에 맞췄고 라이언과 어피치의 점수가 같다면
} else if (info[i] != 0 && info2[i] == info[i]) {
a += score;
}
}
// 라이언과 어피치의 점수 차이
int dif = r - a;
// 라이언의 점수가 높고 max보다 크다면
// 점수가 같은 경우에는 가장 낮은 점수를 더 많이 맞힌 경우가 저장됨
if (dif > max) {
max = dif;
answer = info2;
}
return;
}
}
'코딩 테스트' 카테고리의 다른 글
(Java) 프로그래머스 - k진수에서 소수 개수 구하기 (0) | 2022.08.31 |
---|---|
(Java) 프로그래머스 - 주차 요금 계산 (2) | 2022.08.30 |
(Java) 프로그래머스 - 성격 유형 검사하기 (0) | 2022.08.25 |
(Java) 프로그래머스 - 하노이의 탑 (0) | 2022.08.18 |
(Java) 프로그래머스 - N-Queen (0) | 2022.08.13 |