이번에 풀어본 문제는
프로그래머스 양궁대회 입니다.
import java.util.*;
class Solution {
static int N;
static int max = Integer.MIN_VALUE;
static int [] INFO;
static int [] answer = new int[11];
static boolean isPossible;
public int[] solution(int n, int[] info) {
N = n;
INFO = info;
comb(new int[11],0,0,0,0);
if(!isPossible)
{
answer = new int[1];
answer[0] = -1;
return answer;
}
return answer;
}
static void comb(int [] res, int idx, int cnt,int apeach,int ryan)
{
if(idx == 11)
{
if(cnt < N) res[10] = N-cnt;
if(apeach < ryan)
{
int score = ryan - apeach;
if(max <= score)
{
if(max == score)
{
if(!canChange(answer,res)) return;
}
isPossible = true;
System.arraycopy(res,0,answer,0,11);
max = score;
}
}
return;
}
// 안쏘는경우
int a_point = 0;
res[idx] = 0;
a_point = INFO[idx] > 0 ? 10-idx : 0; // 어피치가 한발이상 쐈으면 점수획득
comb(res,idx+1,cnt,apeach+a_point,ryan);
// 이기는경우
int r_point = 10-idx; // 라이언 점수획득
int tmp_cnt = INFO[idx]+1;
if((cnt+tmp_cnt) <= N)
{
res[idx] = tmp_cnt;
comb(res,idx+1,cnt+tmp_cnt,apeach,ryan+r_point);
}
}
static boolean canChange(int [] fst, int [] sec)
{
for(int i = 10; i >= 0; --i)
{
if(fst[i] < sec[i]) return true;
else if(fst[i] > sec[i]) return false;
}
return false;
}
}
라이언이 불리한 조건의 양궁 대회에서 가장 큰 점수차로 이길 수 있는 경우를 출력하는 문제입니다. 가능한 경우를 조합해, 그중 점수차이가 가장 크고 조건에 부합한 결과를 answer배열에 복사하도록 했습니다.
조합을 만들 때, 해당 점수의 과녁을 아예 쏘지않는 경우와, 어피치보다 한발을 더 맞춰서 점수를 획득하는 경우 두가지로 나누어 조합을 만들었고, 화살이 남았을경우 0점에 모두 털어넣어, 모든 경우의 수를 고려할 수 있도록 해보았습니다.
화살이 남았을 때, 점수차이가 같을 때 우선조건 등의 이유로 1~2가지 테스트 케이스를 통과하지 못했었고, 해당 부분을 수정하다보니 해결은 했지만 조금 난잡해 보이는 코드가 된 것 같습니다.. 코딩테스트 당시 시간이 부족하여 넘어갔던 문제라서 다시 풀어보았는데, 넘어가길 잘했다는 생각이 살~짝 드네요..ㅋㅋㅋㅋㅋ 부가적인 조건들이 조금 까다롭다고 느꼈던 문제입니다! ^^