알고리즘/프로그래머스 카카오

알고리즘) 카카오 블라인드 채용 2020, 외벽 점검

Zin0_0 2020. 5. 8. 20:38
반응형

Kakao Blind Recruitment 2020

외벽 점검

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

제한사항
  • n은 1 이상 200 이하인 자연수입니다.
  • weak의 길이는 1 이상 15 이하입니다.
    • 서로 다른 두 취약점의 위치가 같은 경우는 주어지지 않습니다.
    • 취약 지점의 위치는 오름차순으로 정렬되어 주어집니다.
    • weak의 원소는 0 이상 n - 1 이하인 정수입니다.
  • dist의 길이는 1 이상 8 이하입니다.
    • dist의 원소는 1 이상 100 이하인 자연수입니다.
  • 친구들을 모두 투입해도 취약 지점을 전부 점검할 수 없는 경우에는 -1을 return 해주세요.

 

풀이

너무 어렵게 접근해서 푸는데 너무 많은 시간이 소요됐다. 풀면서 실수한 부분을 살펴보면

첫째) 친구들을 모두 투입해도 점검을 못하면 -1을 리턴하는 부분을 놓쳤다.

둘째) 순열을 쓰지 않고 친구들의 정보가 담긴 Dist를 최대값부터 탐색과 최소값부터 탐색을 모두 해서 결과를 ArrayList에 두고 -1을 제외한 최소값을 반환했는데, 순차적으로 친구들이 탐색할 수 있는 경우가 아닌 뒤죽박죽 순서로 검사해야만 검사할 수 있는 경우가 있었다.

정도 문제점이 있었다.

 

오랜 시간동안 풀지 못해서 다른 분의 풀이를 참고했다. 링크

 

[프로그래머스] 2020 KAKAO BLIND RECRUITMENT 외벽 점검 (Java)

프로그래머스 2020 KAKAO BLIND RECRUITMENT 외벽 점검 : https://programmers.co.kr/learn/courses/30/lessons/60062 코딩테스트 연습 - 외벽 점검 | 프로그래머스 레스토랑을 운영하고 있는 스카피는 레스토랑..

leveloper.tistory.com

풀이 과정을 보면

1. 취약점 부분이 원형이기 때문에, weak[]의 길이 만큼 각각의 요소에 n을 더한 값을 추가하여 새로운 weakList를 만든다.

2. dist의 길이만큼 for문을 돌며 i 개의 순열을 만드는 함수를 호출한다.

3. 순열 결과로 나온 List를 검사하는 메소드에 넘겨 탐색이 가능한지 weakList를 탐색한다.

4. 가능하다면 전역변수로 설정한 boolean타입의 found에 true값을 넣고 for문을 돌고있는 개수 i 를 답에 넣고 모든 메소드를 종료한다.

 4.1 answer는 -1로 초기화해놨기 때문에(못찾는 경우) found 값이 true 일 때만 i 저장

5. 답을 반환

 

코드

import java.util.LinkedList;

public class OuterWall_2019 {
    final static int MIN_ANSWER = 1;
    static LinkedList<Integer> weakList;
    static boolean found;
    static int weakLen;

    public static void main(String[] args) {
//        int n =12;
//        int[] weak = {1,5,6,10};
//        int[] dist = {1,2,3,4};
//        int[] weak = {1, 3, 4, 9, 10};
//        int[] dist = {3, 5, 7};
//        int[] weak = {0,2,11};
//        int[] dist = {3};

        int n = 50;
//        int[] weak = {1, 5, 10, 16, 44, 47};
//        int[] dist = {3,4,6};
        int[] weak = {1, 5, 10, 16, 22, 25};
        int[] dist = {3,4,6};
        System.out.println(solution(n,weak,dist));
    }

    private static int solution(int n, int[] weak, int[] dist) {
        return n ==MIN_ANSWER || weak.length ==MIN_ANSWER ? MIN_ANSWER : findMinPersons(n, weak, dist);
    }

    private static LinkedList<Integer> getWeakList(int n, int[] weak) {    // n 은 2 이상
        weakLen = weak.length;
        LinkedList<Integer> result = new LinkedList<>();

        for(int num : weak) {
            result.offer(num);
        }
        for(int i=0; i<weakLen; i++) {
            result.offer(result.get(i)+n);
        }

        return result;
    }

    private static void permutation(int[] visit, int[] dist, LinkedList<Integer> result, int cnt) {
        if(found) {
            return;
        }
        if(cnt == 0) {  // 조합 완성
            findCase(result);
            return;
        }

        for(int i=0; i<dist.length; i++) {
            if(visit[i] ==0) {
                result.offer(dist[i]);
                visit[i] = 1;
                permutation(visit, dist, result, cnt-1);
                visit[i] =0;
                result.removeLast();
            }
        }
    }

    private static int findMinPersons(int n, int[] weak, int[] dist) {
        weakList = getWeakList(n, weak);
        found = false;
        int answer =-1;

        for(int i=1; i<=dist.length; i++) {
            permutation(new int[dist.length], dist, new LinkedList<>(), i);
            if(found) {
                answer = i;
                break;
            }
        }
        return answer;
    }

    private static void findCase(LinkedList<Integer> distList) {
        for(int idx = 0; idx < weakLen; idx++) {
            int distIdx = 0;
            int person = distList.get(distIdx);
            int prev = idx; // 이전 값
            boolean allDone = true;
            for (int i = idx; i < idx + weakLen; i++) {
                int diff = weakList.get(i) - weakList.get(prev);
                if (person - diff < 0) {    // 더이상 체크할 수 없으면
                    if (distIdx + 1 < distList.size()) {
                        person = distList.get(++distIdx);
                    } else {
                        allDone = false;
                        break;
                    }
                } else {    // 체크할 수 있으면
                    person -= diff;    // 거리만큼 빼줌
                }
                prev = i; // prev 옮기기
            }
            if (allDone) {  // 결과적으로 다 돌았다는거
                found = true;
                break;
            }
        }
    }
}
반응형