IT recording...

[BOJ] 17825 주사위윷놀이 - Java 본문

Algorithm

[BOJ] 17825 주사위윷놀이 - Java

I-one 2022. 4. 28. 17:50

https://www.acmicpc.net/problem/17825

 

17825번: 주사위 윷놀이

첫째 줄에 주사위에서 나올 수 10개가 순서대로 주어진다.

www.acmicpc.net

[풀이]

1. 링크드리스트로 맵을 구성한다.

파란색 라인이 있는 쪽은 isBlue를 true로 설정하고, 자식에 그냥 child, blueChild를 연결함

 

2. 모든 말의 순열을 구하고, 점수를 계산해나간다.

static void permutation(int count){
    if(count>=11){
        Arrays.fill(Mal,root); //처음 말들 초기화
        answer = Math.max(answer,gameStart());
        for(int i=1;i<5;i++){ //말들 초기화
            Mal[i].isHere = false;
        }
        return;
    }
    for(int i=1;i<5;i++){ //말 1~4
        Order[count] = i; //말i가 Order 순서에 들어감
        permutation(count+1);
    }
}

 

- 한 순열을 계산할 때마다 말의 위치들을 초기화시켜주어야 한다.

 

3. 이미 골에 들어간 말을 사용하면 return 0, 이미 말이 있는 곳에 가면 return 0

 

[코드]

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    static StringTokenizer st;
    static int N;
    static int answer;
    static int[] Dice = new int[10+1]; //주사위 1~10
    static int[] Order = new int[10+1]; //말 순서 1~10
    static ArrayList<Integer> OrderArr = new ArrayList<>();
    static Node root = new Node();

    static Node[] Mal = new Node[4+1]; //말 위치 1~4

    public static void main(String[] args) throws Exception{
        //System.setIn(new FileInputStream("src/main/java/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        st = new StringTokenizer(br.readLine());
        for(int i=1;i<11;i++){
            Dice[i] = Integer.parseInt(st.nextToken());
        }
        Arrays.fill(Mal,root); //처음 말들 초기화

        //주사위는 주어졌고, Order만 구하면 됨
        //Order를 하나씩 구하면서 단계를 진행하면 안됨 (백트래킹 어려움) -> Order를 다 구하고 하자
        initMap();
        permutation(1);
        System.out.println(answer);
    }

    static void permutation(int count){
        if(count>=11){
            Arrays.fill(Mal,root); //처음 말들 초기화
            answer = Math.max(answer,gameStart());
            for(int i=1;i<5;i++){ //말들 초기화
                Mal[i].isHere = false;
            }
            return;
        }
        for(int i=1;i<5;i++){ //말 1~4
            Order[count] = i; //말i가 Order 순서에 들어감
            permutation(count+1);
        }
    }

    static int gameStart(){
        int score = 0;
        //Order, Dice 가 주어짐. Order[i] i번째에 존재하는 말(1~4)이 Dice만큼 이동
        boolean[] Goal = new boolean[5];

        for(int t=1;t<11;t++){
            int dice = Dice[t]; //1~5
            int nowMalIndex = Order[t]; //1~4
            Node nowMal = Mal[nowMalIndex]; //지금 어느 노드에 있는지 -> dice만큼 이동시키기

            nowMal.isHere = false; //이동시킬거니까 말 없애주기

            //이미 goal 들어간 말인지 확인
            if(Goal[nowMalIndex]){
                return 0;
            }
            for(int i=0;i<dice;i++){ //dice만큼 반복하면서 노드 이동
                if(i==0 && nowMal.isBlue){ //맨 처음이 blue면 blue로
                    nowMal = nowMal.getChild(true);
                }
                else{
                    nowMal  = nowMal.getChild(false);
                }

                if(nowMal.isEnd){ // 골이면 바로 break
                    Goal[nowMalIndex] = true;
                    break;
                }
                if(i==dice-1){ //마지막이면
                    if(!nowMal.isHere) { //그 자리에 말이 있는지 확인
                        score += nowMal.value;
                        nowMal.isHere = true;
                        Mal[nowMalIndex] = nowMal;
                    }
                    else{
                        return 0;
                    }
                }
            }
        }
        return score;
    }

    static void initMap(){
        Node now = root;
        //40 -> 도착
        Node last40 = new Node(40);
        last40.child = new Node(0);
        last40.child.isEnd = true;

        //25 -> 30 -> 35 -> 40
        Node middle25 = new Node(25);
        Node tmp = middle25.child = new Node(30);
        tmp = tmp.child = new Node(35);
        tmp.child = last40;

        //2,4,6,8,10,13,16,19,25
        now = now.child = new Node(2);
        now = now.child = new Node(4);
        now = now.child = new Node(6);
        now = now.child = new Node(8);
        now = now.child = new Node(10);
        now.isBlue = true;

        tmp = now.blueChild = new Node(13);
        tmp = tmp.child = new Node(16);
        tmp = tmp.child = new Node(19);
        tmp.child = middle25;

        now = now.child = new Node(12);
        now = now.child = new Node(14);
        now = now.child = new Node(16);
        now = now.child = new Node(18);
        now = now.child = new Node(20);
        now.isBlue = true;

        tmp = now.blueChild = new Node(22);
        tmp = tmp.child = new Node(24);
        tmp.child = middle25;

        now = now.child = new Node(22);
        now = now.child = new Node(24);
        now = now.child = new Node(26);
        now = now.child = new Node(28);
        now = now.child = new Node(30);
        now.isBlue = true;

        tmp = now.blueChild = new Node(28);
        tmp = tmp.child = new Node(27);
        tmp = tmp.child = new Node(26);
        tmp.child = middle25;

        now = now.child = new Node(32);
        now = now.child = new Node(34);
        now = now.child = new Node(36);
        now = now.child = new Node(38);
        now.child = last40;
    }

    static class Node{
        int value; //점수
        boolean isEnd; //골인지
        boolean isBlue; //파란색 부분인지
        boolean isHere; //말이 여기 서있는지
        Node child;
        Node blueChild;

        public Node(int value) {
            this.value = value;
        }

        public Node() {
        }

        Node getChild(boolean imBlue){
            if(!imBlue)
                return child; //그냥 길
            else
                return blueChild; //파란길
        }
    }
}

[느낀점]

소요시간 : 2 days

미쳤다 그냥 

이걸 어떻게 푸냐

후........ 포기 10번 넘게 하려고 했는데 정신력으로 붙잡고 있었다.

아니 일단 링크드리스트 구현하는것부터 빡치고, 세부 조건들 생각하는 것도 빡치고

ㅜㅜㅜㅜㅜ 더 풀어봐야지..

 

'Algorithm' 카테고리의 다른 글

[PG] 표 편집 - Java  (0) 2022.05.11
[BOJ] 2629 양팔저울 - Java  (0) 2022.05.11
[BOJ] 17822 원판돌리기 - Java  (0) 2022.04.26
[BOJ] 17837 새로운게임2 - Java  (0) 2022.04.26
[BOJ] 17779 게리맨더링 2 -Java  (0) 2022.04.25
Comments