[프로그래머스/Java] 양궁대회 코드 및 해설

Jake·2022년 2월 15일
0

PS

목록 보기
2/14
  • 설계:
class Solution {
    int[] maxRyanShoot;
    int maxScoreDiff;

    public int[] solution(int n, int[] info) {//info : 10 to 0
        maxRyanShoot = new int[11];
        maxScoreDiff = 0;

        for(int bitmask = 0; bitmask < (1<<11); bitmask++) {
            if(checkBitmaskValidity(bitmask, info) == false) continue;

            int[] tempRyanShoot = getRyanShoot(bitmask);

            int scoreDiff = getScoreDiff(bitmask);
            if(scoreDiff < maxScoreDiff) {
                continue;
            }
            else if(scoreDiff == maxScoreDiff) {
                if(checkMoreLowerScore(tempRyanShoot)) {
                    maxRyanShoot = tempRyanShoot;
                }
            }
            else {
                maxRyanShoot = tempRyanShoot;
            }

        }
        return maxRyanShoot;
    }

    //n개의 화살로 이 비트마스크가 가능한지 체크
    public boolean checkBitmaskValidity(int bitmask, int[] info) {
        
    }
		
		//라이언이 쏜 화살 정보(어피치의 info[]와 같은 역할)
		public int[] getRyanShoot(int bitmask) {
				
		}
	
		//어피치와 라이언의 점수 차이(라이언 - 어피치)
		public int getScoreDiff(int bitmask) {
		
		}

    //적은 점수가 더 많은지 체크
    public boolean checkMoreLowerScore(int[] tempRyanShoot) {
        
    }
}
  • 구현:
class Solution {
        int[] maxRyanShoot;
        int maxScoreDiff;
        int N;

        public int[] solution(int n, int[] info) {//info : 10 to 0
            maxRyanShoot = new int[11];
            maxScoreDiff = 0;
            N = n;

            for(int bitmask = 0; bitmask < (1<<11); bitmask++) {//bitmask 11010 : 라이언이 4, 3, 1점 획득
                int cnt = checkBitmaskValidity(bitmask, info);
                if(cnt > N) continue;

                int[] tempRyanShoot = getRyanShoot(bitmask, info, cnt);

                int tempScoreDiff = getScoreDiff(bitmask, info);
                if(tempScoreDiff < maxScoreDiff) {
                    continue;
                }
                else if(tempScoreDiff == maxScoreDiff) {
                    if(checkMoreLowerScore(tempRyanShoot)) {
                        maxRyanShoot = tempRyanShoot;
                    }
                }
                else {
                    maxScoreDiff = tempScoreDiff;
                    maxRyanShoot = tempRyanShoot;
                }
            }

            return maxScoreDiff == 0 ? new int[]{-1} : maxRyanShoot;
        }

        //n개의 화살로 이 비트마스크가 가능한지 체크
        public int checkBitmaskValidity(int bitmask, int[] info) {
            int cnt = 0;
            for(int i = 0; i <= 10; i++) {
                if((bitmask & (1<<i)) > 0) {
                    int toWinApeach = info[10-i] + 1;
                    cnt += toWinApeach;
                }
            }
            return cnt;
        }

        public int[] getRyanShoot(int bitmask, int[] info, int cnt) {
            int[] tempRyanShoot = new int[11];
            for(int i = 0; i <= 10; i++) {//0점부터 10점까지 루프
                if((bitmask & 1<<i) > 0) {
                    int toWinApeach = info[10-i] + 1;
                    tempRyanShoot[10-i] = toWinApeach;
                }
            }
            tempRyanShoot[10] += N-cnt;//남은 화살은 제일 점수가 작은 곳에 다 넣어줍니다
            return tempRyanShoot;
        }

        //어피치와 라이언의 점수 차이(라이언 - 어피치)
        public int getScoreDiff(int bitmask, int[] info) {
            int ryanScore = 0;
            int apeachScore = 0;
            for(int i = 0; i <= 10; i++) {
                if ((bitmask & 1 << i) > 0) {
                    ryanScore += i;
                } else {
                    if(info[10-i] > 0) {
                        apeachScore += i;
                    }
                }
            }
            return ryanScore - apeachScore;
        }

        //적은 점수가 더 많은지 체크
        public boolean checkMoreLowerScore(int[] tempRyanShoot) {
            for(int i = 0; i <= 10; i++) {
                if(tempRyanShoot[10-i] > maxRyanShoot[10-i]) {
                    return true;
                } else if(tempRyanShoot[10-i] == maxRyanShoot[10-i]) {
                    continue;
                }
                else {
                    return false;
                }
            }
            return true;
        }
    }
  • 남은 화살을 0점에 다 넣어주는 로직:
    • 비트마스크에서 모든 케이스를 처리하기 때문에 원칙적으로는 비트마스크에서 1로 켜진 점수 중에서 가장 낮은 점수에 남은 화살을 모두 넣어주는 것이 맞습니다
    • 하지만 이 경우 코드가 조금 길어집니다
    • 같은 점수차이라면, 무조건 0점에 화살이 더 많은 케이스가 정답이 되기 때문에 0점에 남은 화살을 넣어주는 코드로도 정답을 도출할 수 있습니다.
profile
Java/Spring Back-End Developer

0개의 댓글