깊이 탐색으로 이기고 지는 케이스에 대해 경우에 대한 결과를 찾아오고
그 결과에서 최대 점수에 동점이 있는 경우 낮은 점수에서 높은 점수인 케이스를 찾는다
깊이 탐색에서 array
를 넘겨주기 때문에 매 순간 clone
을 해서 넘겨주었다.
최대 점수를 찾고 나서, 낮은 점수 찾는 부분에 대한 문제가 있다면 아래 케이스를 돌려
정상적으로 나오는지 확인해야 한다.
int[] ints1 = {2,3,1,0,0,0,0,1,3,0,0};
int[] ints2 = {2,1,0,2,0,0,0,2,3,0,0};
int[] ints3 = {2,1,0,2,0,0,0,2,3,1,0};
int[] ints4 = {2,1,0,2,0,0,0,3,3,1,0};
public List<int[][]> arrowScoreList = new ArrayList<>();
public int[] solution(int n, int[] info) {
arrowScoreList = new ArrayList<>();
int[] answer = {};
int[][] playGame = {info, {0,0,0,0,0,0,0,0,0,0,0}};
int[][] playGame2 = cloneArray(playGame);
this.calcArrowScore(n, 0, false, playGame);
this.calcArrowScore(n, 0, true, playGame2);
if(arrowScoreList.isEmpty()){
answer = new int[]{-1};
}else if(arrowScoreList.size() != 1){
int[][] highestScoreToFristLowHighest = findHighestScoreToFristLowHighest();
answer = highestScoreToFristLowHighest[1];
} else{
answer = arrowScoreList.get(0)[1];
}
for (int i : answer) {
System.out.print(i+"\t");
}
return answer;
}
void calcArrowScore(int leftArrow, int index, boolean div, int[][] info){
int[][] list = cloneArray(info);
if(div){
Integer fristPlayerArrowCount = list[0][index];
if (leftArrow > fristPlayerArrowCount) {
list[0][index] = 0;
list[1][index] = fristPlayerArrowCount+1;
leftArrow -= fristPlayerArrowCount+1;
}
}
if(index >= 10 && leftArrow > 0){
list[1][10] = list[1][10] + leftArrow;
leftArrow = 0;
}
if (leftArrow <= 0 || index >= 10) {
if(compareScoure(list) < 0){
if(arrowScoreList.isEmpty()){
arrowScoreList.add(list);
}else{
int compareScoure = compareDiffScore(arrowScoreList.get(0), list);
if (compareScoure < 0) {
arrowScoreList = new ArrayList();
arrowScoreList.add(list);
} else if (compareScoure == 0) {
arrowScoreList.add(list);
}
}
}
}else {
this.calcArrowScore(leftArrow, ++index, true, list);
this.calcArrowScore(leftArrow, index, false, list);
}
}
int[][] cloneArray(int[][] playerScore){
int[][] cloneArray = new int[playerScore.length][playerScore[0].length];
for(int i=0; i<cloneArray.length; i++){
System.arraycopy(playerScore[i], 0, cloneArray[i], 0, playerScore[0].length);
}
return cloneArray;
}
int compareScoure(int[][] gameScore){
int firstPlayer = sumTotalScore(gameScore[0]);
int secondPlayer = sumTotalScore(gameScore[1]);
if(firstPlayer > secondPlayer) return 1;
if(firstPlayer == secondPlayer) return 0;
else return -1;
}
int compareDiffScore(int[][] firstGame, int[][] secondGame){
int gameScore = diffSource(firstGame);
int gameScore2 = diffSource(secondGame);
if(gameScore > gameScore2) return 1;
else if (gameScore == gameScore2) return 0;
else return -1;
}
int diffSource(int[][] gameScore){
int firstPlayer = sumTotalScore(gameScore[0]);
int secondPlayer = sumTotalScore(gameScore[1]);
return secondPlayer - firstPlayer;
}
int sumTotalScore(int[] playerScore){
int sumTotalScore = 0;
sumTotalScore += playerScore[0] != 0 ? 10 : 0;
sumTotalScore += playerScore[1] != 0 ? 9 : 0;
sumTotalScore += playerScore[2] != 0 ? 8 : 0;
sumTotalScore += playerScore[3] != 0 ? 7 : 0;
sumTotalScore += playerScore[4] != 0 ? 6 : 0;
sumTotalScore += playerScore[5] != 0 ? 5 : 0;
sumTotalScore += playerScore[6] != 0 ? 4 : 0;
sumTotalScore += playerScore[7] != 0 ? 3 : 0;
sumTotalScore += playerScore[8] != 0 ? 2 : 0;
sumTotalScore += playerScore[9] != 0 ? 1 : 0;
return sumTotalScore;
}
int[][] findHighestScoreToFristLowHighest(){
List<int[][]> diffLisf = new ArrayList<int[][]>();
for(int i = 10; i >=0; i--){
boolean isSameScore = false;
int lowScore = 0;
for (int j = 0; j < arrowScoreList.size(); j++) {
int score = arrowScoreList.get(j)[1][i];
if(score == lowScore && lowScore > 0){
isSameScore = true;
diffLisf.add(arrowScoreList.get(j));
}else if (score > 0 && score > lowScore) {
diffLisf = new ArrayList<>();
diffLisf.add(arrowScoreList.get(j));
isSameScore = false;
lowScore = score;
}
}
if (!diffLisf.isEmpty()) {
arrowScoreList = diffLisf;
}
if(!isSameScore && lowScore > 0){
break;
}
}
return arrowScoreList.get(0);
}