본문 바로가기
PS/BOJ

[자바] 백준 27162 - Yacht Dice (java)

by Nahwasa 2023. 1. 15.

 문제 : boj27162


 

필요 알고리즘 개념

  • 많은 조건 분기, 구현, 브루트포스
    • 많은 조건을 분기해줘야 하는 구현문제이다.

※ 제 코드에서 왜 main 함수에 로직을 직접 작성하지 않았는지, 왜 Scanner를 쓰지 않고 BufferedReader를 사용했는지 등에 대해서는 '자바로 백준 풀 때의 팁 및 주의점' 글을 참고해주세요. 백준을 자바로 풀어보려고 시작하시는 분이나, 백준에서 자바로 풀 때의 팁을 원하시는 분들도 보시는걸 추천드립니다.

 


 

풀이

  한 함수에서 if문으로 모두 처리하게 되면 디버깅이 쉽지 않다. 내 경우엔 클래스로 구성을 나누었다.

Pedigree 라는 인터페이스가 있는데, 각 족보를 뜻한다. 내부에 maxScore(int[] arr)만 있고 해당 Pedgree의 구현체로 얻을 수 있는 최고의 점수를 얻는 함수이다.

 

  Ones, Twos,.. 등의 모든 족보들은 Pedgree 인터페이스의 구현체이다. 다만 Ones부터 Sixes는 최고의 점수를 얻는 코드가 거의 동일할 것이므로 별도로 OneToSix 클래스로 빼서 코드 재사용(서브클래싱)을 해줬다.

 

  입력받은 YN... 문자열에 따라 사용가능한 족보의 객체를 생성해서 ArrayList에 넣는다. 그리고 고정한 주사위의 눈의 수 3개를 입력받아 ArrayList의 각 족보 후보들에게 넣어 그 중 maxScore의 최대치를 찾는 형태로 코드를 구성했다.

 

  각 Pedigree의 구현체는 다음과 같은 로직으로 maxScore를 찾도록 했다. 입력으로 주어진 고정한 주사위의 눈 3개를 담은 배열을 arr이라고 하겠다.

  • Ones : arr에 있는 1의 갯수를 센 후, 나머지 두 주사위가 '1'이 떴다고 생각하면 최대치이다.
  • Twos~Sixes : Ones와 마찬가지다.
  • Four of a Kind : 어차피 5개가 동일해도 4개의 총합을 출력해야 하므로, arr에서 동일한 값이 2개만 있다면 나머지 두 개를 해당 값으로 출력하면 된다. 따라서 arr에 있는 동일한 값 2개의 눈 * 4가 최대다.
  • Full House : arr에 동일한 값이 3개인 경우 -> 나머지 2개는 arr의 동일한 값 3개가 '6'인 경우 5를 선택하고, 그 외에는 6을 선택하면 된다. / arr에 동일한 값이 2개인 경우(예를들어 6 6 5) -> 나머지 2개는 6, 5를 택하거나 5,5를 택하면 된다. 따라서 둘 중 큰 값이 최대치다.
  • Little Straight : arr에 '6'이 없고 모두 다르다면 30점
  • Big Straight : arr에 '1'이 없고 모두 다르다면 30점
  • Yacht : arr의 눈이 모두 같다면 50점
  • Choice : 나머지 두 개는 무조건 6을 고르면 된다.

 


 

코드 : github

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

interface Pedigree {
    public int maxScore(int[] arr);
}
class OneToSix {
    public int calc(int[] arr, int target) {
        int sum = target*2;
        for (int i = 0; i < 3; i++)
            if (arr[i] == target) sum+=target;
        return sum;
    }
}
class Ones extends OneToSix implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        return calc(arr, 1);
    }
}
class Twos extends OneToSix implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        return calc(arr, 2);
    }
}
class Threes extends OneToSix implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        return calc(arr, 3);
    }
}
class Fours extends OneToSix implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        return calc(arr, 4);
    }
}
class Fives extends OneToSix implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        return calc(arr, 5);
    }
}
class Sixes extends OneToSix implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        return calc(arr, 6);
    }
}
class FourOfAKind implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        if (arr[0]==arr[1] || arr[0]==arr[2])
            return arr[0]*4;
        if (arr[1]==arr[2])
            return arr[1]*4;
        return 0;
    }
}
class FullHouse implements Pedigree {
    private int calc(int couple, int solo) {
        return couple*3+solo*2;
    }

    @Override
    public int maxScore(int[] arr) {
        if (arr[0] == arr[1] && arr[1] == arr[2]) {
            if (arr[0] == 6)
                return 6*3+5*2;
            else
                return arr[0]*3+6*2;
        }
        if (arr[0] == arr[1] && arr[0] != arr[2]) {
            return Math.max(calc(arr[0], arr[2]), calc(arr[2], arr[0]));
        }
        if (arr[0] == arr[2] && arr[0] != arr[1] || arr[1] == arr[2] && arr[0] != arr[1]) {
            return Math.max(calc(arr[0], arr[1]), calc(arr[1], arr[0]));
        }
        return 0;
    }
}
class LittleStraight implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        if (arr[0] == 6 || arr[1] == 6 || arr[2] == 6)
            return 0;
        int[] cnt = new int[7];
        for (int i = 0; i < 3; i++)
            if (++cnt[arr[i]]==2) return 0;
        return 30;
    }
}
class BigStraight implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        if (arr[0] == 1 || arr[1] == 1 || arr[2] == 1)
            return 0;
        int[] cnt = new int[7];
        for (int i = 0; i < 3; i++)
            if (++cnt[arr[i]]==2) return 0;
        return 30;
    }
}
class Yacht implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        if (arr[0] == arr[1] && arr[1] == arr[2]) {
            return 50;
        }
        return 0;
    }
}
class Choice implements Pedigree {
    @Override
    public int maxScore(int[] arr) {
        return arr[0]+arr[1]+arr[2]+6*2;
    }
}

public class Main {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private void solution() throws Exception {
        String str = br.readLine();
        int[] arr = new int[3];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i < 3; i++) arr[i] = Integer.parseInt(st.nextToken());

        List<Pedigree> pedigrees = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            if (str.charAt(i) == 'N') continue;
            switch (i) {
                case 0: pedigrees.add(new Ones()); break;
                case 1: pedigrees.add(new Twos()); break;
                case 2: pedigrees.add(new Threes()); break;
                case 3: pedigrees.add(new Fours()); break;
                case 4: pedigrees.add(new Fives()); break;
                case 5: pedigrees.add(new Sixes()); break;
                case 6: pedigrees.add(new FourOfAKind()); break;
                case 7: pedigrees.add(new FullHouse()); break;
                case 8: pedigrees.add(new LittleStraight()); break;
                case 9: pedigrees.add(new BigStraight()); break;
                case 10: pedigrees.add(new Yacht()); break;
                case 11: pedigrees.add(new Choice()); break;
            }
        }

        int max = 0;
        for (Pedigree cur : pedigrees) {
            max = Math.max(max, cur.maxScore(arr));
        }
        System.out.println(max);
    }

    public static void main(String[] args) throws Exception {
        new Main().solution();
    }
}

댓글