문제 링크
https://programmers.co.kr/learn/courses/30/lessons/72415
예상 난이도
S2 - G5
알고리즘 분류
BFS, 시뮬레이션, 브루트 포스, DP
풀이
뭔가 삼성 A형스러운 문제입니다. 일단 카드의 종류가 최대 6가지이므로 제거할 종류의 순서를 정할 때 6!이고 각 카드는 종류별로 2장씩이므로 둘 중에서 어느 것을 먼저 제거할지 정해야하는데 일단은 이 부분을 무시하겠습니다.
다음으로 매번 현재 커서의 위치에서 카드까지 도달하기 위한 최단거리를 구해야 하는데, 코드 좀 치시는 분들은 2차원 배열에서 가중치가 1인 상황에서의 최단거리다 하면 바로 눈이 돌아가야합니다.
대놓고 BFS입니다.
카드를 2번, 3번, 1번 순으로 지우겠다고 정했을 때 2L→2R →3L →3R →1L →1R 순으로 방문할 수도 있고 2R→2L →3L →3R →1L →1R 순으로 방문할 수도 있고, 2L→2R →3R →3L →1L →1R 순으로 방문할 수도 있고, ... 총 23가지의 가능한 순서가 존재합니다.
카드 종류는 총 6가지이니 이를 감안해 시간복잡도를 계산해보면 6! * 26개의 가능한 순서가 있고 각 순서에 대해 BFS를 총 12번, 각 BFS는 대충 O(16)이니 대략 O(107) 정도가 됩니다. 이렇게 짜면 C++, Java는 통과되는데 Python에서는 시간 초과가 발생합니다.
Python에서는 여기다가 DP까지 끼얹어야 합니다. 저 식을 그대로 따라치기가 너무 귀찮으니 알아서 위의 그림을 참고해주세요. 직전에 L에서 R로 갔는지, R에서 L로 갔는지를 가지고 DP를 돌려서 시간복잡도를 떨궈야합니다. C++, Java에서는 DP를 안해도 되지만 그냥 둘 다 DP까지 넣은 코드로 두었습니다.
dist 함수에서 &를 이용해 매번 board를 복사하는 대신 reference로 이용했습니다. 6!의 순서를 정하는건 next_permutation을 사용했습니다.
itertools.permutations를 활용했습니다.
Java에는 permutation 관련 라이브러리가 없기 때문에 직접 구현을 해야 합니다. 저는 백트래킹을 이용해 구현했습니다.
관련 강의
0x09강 - BFS
0x0C강 - 백트래킹
0x0D강 - 시뮬레이션
0x10강 - 다이나믹 프로그래밍
'알고리즘 > Programmers' 카테고리의 다른 글
[2021 카카오 채용연계형 인턴십] Q2. 거리두기 확인하기 (C++, Python, Java) (2) | 2021.08.16 |
---|---|
[2021 카카오 채용연계형 인턴십] Q1. 숫자 문자열과 영단어 (C++, Python, Java) (0) | 2021.08.16 |
[2021 KAKAO Blind Recruitment] Q7. 매출 하락 최소화 (C++, Python, Java) (0) | 2021.08.15 |
[2021 KAKAO Blind Recruitment] Q5. 광고 삽입 (C++, Python, Java) (0) | 2021.08.15 |
[2021 KAKAO Blind Recruitment] Q4. 합승 택시 요금 (C++, Python, Java) (2) | 2021.08.15 |
[2021 KAKAO Blind Recruitment] Q3. 순위 검색 (C++, Python, Java) (0) | 2021.08.15 |