[2020 KAKAO BLIND RECRUITMENT] 기둥과 보 설치

Titu·2021년 12월 9일
0

Algorithm

목록 보기
26/28

2020 KAKAO BLIND RECRUITMENT 기둥과 보 설치

유형

  • 이차원 배열

코드

import java.util.*;

class Solution {
    class Result implements Comparable<Result> {
        int x;
        int y;
        int structure;

        public Result(int x, int y, int structure) {
            this.x = x;
            this.y = y;
            this.structure = structure;
        }

        @Override
        public int compareTo(Result o) {
            // x좌표 기준으로 오름차순 정렬
            if(this.x > o.x) {
                return 1;
            } else if(this.x < o.x) {
                return -1;
            } else if(this.x == o.x) {
                // x좌표가 같을 경우 y좌표 기준으로 오름차순 정렬
                if(this.y > o.y) {
                    return 1;
                } else if(this.y < o.y) {
                    return -1;
                } else if(this.y == o.y) {
                    // x, y좌표가 모두 같은 경우 기둥이 보보다 앞에 오면 됨
                    // 기둥 0, 보 1로 오름차순 정렬
                    if(this.structure > o.structure) {
                        return 1;
                    } else if(this.structure < o.structure) {
                        return -1;
                    }
                }
            }
            return 0;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Result result = (Result) o;
            return x == result.x && y == result.y && structure == result.structure;
        }
    }

    public int[][] solution(int n, int[][] build_frame) {
        List<Result> resultList = new ArrayList<>();

        for (int i = 0; i < build_frame.length; i++) {
            int x = build_frame[i][0];
            int y = build_frame[i][1];
            int structure = build_frame[i][2];
            int action = build_frame[i][3];

            execute(resultList, x, y, structure, action);
        }

        Collections.sort(resultList);

        int[][] answer = new int[resultList.size()][3];
        for (int i = 0; i < answer.length; i++) {
            answer[i][0] = resultList.get(i).x;
            answer[i][1] = resultList.get(i).y;
            answer[i][2] = resultList.get(i).structure;
        }

        return answer;
    }

    private void execute(List<Result> resultList, int x, int y, int structure, int action) {
        boolean success = false;
        // 삭제 하는 경우
        if(action == 0) {
            success = canUninstall(resultList, x, y, structure);
            if(success == false) {
                resultList.add(new Result(x, y, structure));
            }
        }
        // 설치 하는 경우
        else if(action == 1) {
            success = canInstall(resultList, x, y, structure);
            if(success) {
                resultList.add(new Result(x, y, structure));
            }
        }
    }

    private boolean canUninstall(List<Result> resultList, int x, int y, int structure) {
        boolean success= true;

        resultList.remove(new Result(x, y, structure));

        for (Result result: resultList) {
            success = canInstall(resultList, result.x, result.y, result.structure);
            if(success == false) {
                return false;
            }
        }
        return success;
    }

    private boolean canInstall(List<Result> resultList, int x, int y, int structure) {
        boolean success= false;
        // 기둥을 짓는 경우
        if(structure == 0) {
            // 기둥이 바닥 위에 있는 경우
            if(y == 0) {
                success = true;
            } else {
                // 기둥이 다른 기둥 위에 있거나
                // 기둥이 보의 한쪽 끝 부분 위에 있는 경우
                if(resultList.contains(new Result(x, y - 1, 0))
                    || resultList.contains(new Result(x - 1, y, 1))
                    || resultList.contains(new Result(x, y, 1))) {
                    success = true;
                }
           }
        }
        // 보를 짓는 경우
        else if(structure == 1) {
            // 보의 한쪽 끝 부분이 기둥 위에 있거나
            // 보의 양쪽 끝 부분이 다른 보와 동시에 연결되어 있는 경우
            if(resultList.contains(new Result(x, y - 1, 0))
                || resultList.contains(new Result(x + 1, y - 1, 0))
                || (resultList.contains(new Result(x - 1, y, 1)) && resultList.contains(new Result(x + 1, y, 1)))) {
                success = true;
            }
        }
        return success;
    }
}
profile
This is titu

0개의 댓글