https://school.programmers.co.kr/learn/courses/30/lessons/87694
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
1. 문제 설명
다음과 같은 다각형 모양 지형에서 캐릭터가 아이템을 줍기 위해 이동하려 합니다.

지형은 각 변이 x축, y축과 평행한 직사각형이 겹쳐진 형태로 표현하며, 캐릭터는 이 다각형의 둘레(굵은 선)를 따라서 이동합니다.
만약 직사각형을 겹친 후 다음과 같이 중앙에 빈 공간이 생기는 경우, 다각형의 가장 바깥쪽 테두리가 캐릭터의 이동 경로가 됩니다.

단, 서로 다른 두 직사각형의 x축 좌표 또는 y축 좌표가 같은 경우는 없습니다.

즉, 위 그림처럼 서로 다른 두 직사각형이 꼭짓점에서 만나거나, 변이 겹치는 경우 등은 없습니다.
다음 그림과 같이 지형이 2개 이상으로 분리된 경우도 없습니다.

한 직사각형이 다른 직사각형 안에 완전히 포함되는 경우 또한 없습니다.

지형을 나타내는 직사각형이 담긴 2차원 배열 rectangle, 초기 캐릭터의 위치 characterX, characterY, 아이템의 위치 itemX, itemY가 solution 함수의 매개변수로 주어질 때, 캐릭터가 아이템을 줍기 위해 이동해야 하는 가장 짧은 거리를 return 하도록 solution 함수를 완성해주세요.
제한사항
- rectangle의 세로(행) 길이는 1 이상 4 이하입니다.
- rectangle의 원소는 각 직사각형의 [좌측 하단 x, 좌측 하단 y, 우측 상단 x, 우측 상단 y] 좌표 형태입니다.
- 직사각형을 나타내는 모든 좌표값은 1 이상 50 이하인 자연수입니다.
- 서로 다른 두 직사각형의 x축 좌표, 혹은 y축 좌표가 같은 경우는 없습니다.
- 문제에 주어진 조건에 맞는 직사각형만 입력으로 주어집니다.
- charcterX, charcterY는 1 이상 50 이하인 자연수입니다.
- 지형을 나타내는 다각형 테두리 위의 한 점이 주어집니다.
- itemX, itemY는 1 이상 50 이하인 자연수입니다.
- 지형을 나타내는 다각형 테두리 위의 한 점이 주어집니다.
- 캐릭터와 아이템의 처음 위치가 같은 경우는 없습니다.
- 전체 배점의 50%는 직사각형이 1개인 경우입니다.
- 전체 배점의 25%는 직사각형이 2개인 경우입니다.
- 전체 배점의 25%는 직사각형이 3개 또는 4개인 경우입니다.
입출력 예
[[1,1,7,4],[3,2,5,5],[4,3,6,9],[2,6,8,8]] | 1 | 3 | 7 | 8 | 17 |
[[1,1,8,4],[2,2,4,9],[3,6,9,8],[6,3,7,7]] | 9 | 7 | 6 | 1 | 11 |
[[1,1,5,7]] | 1 | 1 | 4 | 7 | 9 |
[[2,1,7,5],[6,4,10,10]] | 3 | 1 | 7 | 10 | 15 |
[[2,2,5,5],[1,3,6,4],[3,1,4,6]] | 1 | 4 | 6 | 3 | 10 |
입출력 예 #1

캐릭터 위치는 (1, 3)이며, 아이템 위치는 (7, 8)입니다. 위 그림과 같이 굵은 선을 따라 이동하는 경로가 가장 짧습니다.
2. 시나리오
- 겹쳐진 사각형들의 테두리와 내부를 구분할 수 있어야 한다.
- 사각형의 내부는 2로 채운다.
- 사각형의 테두리는 1로 채운다.
이미 2로 채워져있다면 다른 사각형의 내부이기 때문에 그대로 둔다. - 모든 사각형에 대해 반복하고 나면, 겹쳐진 것을 고려하여 테두리는 1, 내부는 2로 채워진다.
- 최소 거리이기 때문에 BFS로 탐색한다.
- 상, 하, 좌, 우 4방향을 탐색하며 방문하지 않았고, 테두리(1)인 경우 점을 큐에 넣으며 진행한다.
- 하지만 반례가 있다.
- 아래의 그림처럼 ㄷ자로 테두리가 형성되면, 어디가 다음으로 가야할 테두리인지 구분할 수 없다.
- 그래서 길이를 2배 늘려주고, 길이의 / 2를 반환한다.
3. 코드
import java.util.*;
class Solution {
static int[][] arr = new int[101][101];
static boolean[][] visit = new boolean[101][101];
static int[] dx = {-1, 0, 1, 0};
static int[] dy = {0, 1, 0, -1};
public int solution(int[][] rectangle, int characterX, int characterY, int itemX, int itemY) {
draw(rectangle);
return bfs(characterX * 2, characterY * 2, itemX * 2, itemY * 2);
}
public int bfs(int x, int y, int a, int b) {
Deque<Node> queue = new ArrayDeque<>();
queue.add(new Node(x, y, 0));
visit[y][x] = true;
while (!queue.isEmpty()) {
Node poll = queue.pollFirst();
if (poll.x == a && poll.y == b)
return poll.w / 2;
for (int i = 0 ; i < 4; i++) {
int nextX = poll.x + dx[i];
int nextY = poll.y + dy[i];
if (nextX >= 1 && nextX <= 100 && nextY >= 1 && nextY <= 100
&& !visit[nextY][nextX] && arr[nextY][nextX] == 1) {
queue.add(new Node(nextX, nextY, poll.w + 1));
visit[nextY][nextX] = true;
}
}
}
return -1;
}
public void draw(int[][] rectangle) {
for (int i = 0; i < rectangle.length; i++) {
int x1 = rectangle[i][0] * 2;
int y1 = rectangle[i][1] * 2;
int x2 = rectangle[i][2] * 2;
int y2 = rectangle[i][3] * 2;
for (int j = x1; j <= x2; j++) {
for (int k = y1; k <= y2; k++) {
if (j == x1 || j == x2 || k == y1 || k == y2) {
if (arr[k][j] == 2)
continue;
arr[k][j] = 1;
} else {
arr[k][j] = 2;
}
}
}
}
}
public class Node {
int x, y, w;
public Node (int x, int y, int w) {
this.x = x;
this.y = y;
this.w = w;
}
}
}
'알고리즘 고득점 Kit' 카테고리의 다른 글
프로그래머스 가장 먼 노드 Java (0) | 2024.04.02 |
---|---|
프로그래머스 주식가격 Java (0) | 2024.04.02 |
프로그래머스 단어 변환 Java (0) | 2024.03.31 |
프로그래머스 네트워크 Java (0) | 2024.03.31 |
프로그래머스 다리를 지나는 트럭 Java (0) | 2024.03.30 |