2026.07.18. 02:38
문제 설명
다음과 같은 다각형 모양 지형에서 캐릭터가 아이템을 줍기 위해 이동하려 합니다.
지형은 각 변이 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개인 경우입니다.
입출력 예
rectanglecharacterXcharacterYitemXitemYresult[[1,1,7,4],[3,2,5,5],[4,3,6,9],[2,6,8,8]]137817[[1,1,8,4],[2,2,4,9],[3,6,9,8],[6,3,7,7]]976111[[1,1,5,7]]11479[[2,1,7,5],[6,4,10,10]]3171015[[2,2,5,5],[1,3,6,4],[3,1,4,6]]146310
입출력 예 설명
입출력 예 #1
캐릭터 위치는 (1, 3)이며, 아이템 위치는 (7, 8)입니다. 위 그림과 같이 굵은 선을 따라 이동하는 경로가 가장 짧습니다.
입출력 예 #2
캐릭터 위치는 (9, 7)이며, 아이템 위치는 (6, 1)입니다. 위 그림과 같이 굵은 선을 따라 이동하는 경로가 가장 짧습니다.
입출력 예 #3
캐릭터 위치는 (1, 1)이며, 아이템 위치는 (4, 7)입니다. 위 그림과 같이 굵은 선을 따라 이동하는 경로가 가장 짧습니다.
입출력 예 #4, #5
설명 생략
import java.util.*;
class Solution {
boolean[][] grid = new boolean[51*2][51*2];
boolean[][] visited = new boolean[51*2][51*2];
int[][] vectors = new int[][]{{-1 ,0},{1 ,0},{0, -1}, {0 ,1}};
public static class Node{
public int x;
public int y;
public int dist;
public Node(int x, int y, int dist){
this.x = x;
this.y = y;
this.dist = dist;
}
}
public int solution(int[][] rectangle, int characterX, int characterY, int itemX, int itemY) {
int answer = 0;
drawRectangle(rectangle);
Queue<Node> q = new LinkedList<>();
q.offer(new Node(characterX*2, characterY*2, 0));
while(!q.isEmpty()){
Node node = q.poll();
if(node.x == itemX * 2 && node.y == itemY * 2){
return node.dist/2;
}
for(int[] v : vectors){
int ny = node.y+v[0];
int nx = node.x+v[1];
if(grid[ny][nx] && !visited[ny][nx]){
visited[ny][nx] = true;
q.offer(new Node( nx, ny , node.dist + 1));
}
}
}
return answer;
}
private void drawRectangle(int[][] rectangle){
// 테두리 그리기.
for(int[] r : rectangle){
int lx = r[0]*2;
int ly = r[1]*2;
int rx = r[2]*2;
int ry = r[3]*2;
for(int i = ly; i <= ry; i++){
grid[i][lx] = true;
grid[i][rx] = true;
}
for(int j = lx; j <= rx; j++){
grid[ly][j] = true;
grid[ry][j] = true;
}
}
// 내부 지우기
for(int[] r : rectangle){
int lx = r[0]*2;
int ly = r[1]*2;
int rx = r[2]*2;
int ry = r[3]*2;
for(int i = ly + 1; i < ry; i++){
for(int j = lx + 1; j < rx; j++ ){
grid[i][j] = false;
}
}
}
}
// 디버깅용
private void printGrid(){
for(int i = 20; i >= 0; i--){
for(int j = 0; j <= 20; j++){
if(grid[i][j]){
System.out.print('1');
}else {
System.out.print('0');
}
}
System.out.println();
}
}
}1. 풀이 자체는 BFS를 이용한 최단거리 조회.
사각형 그리기
일단 grid를 만들고 사각형 개체의 라인마다 true 처리를 함.
그리고 사각형 배열을 한번 더 순회하면서 사각형 내부를 false 처리.
grid에서 bfs로 최단거리 조회
특정 테스트에서 최단거리가 작게 나오는 문제가 발생
문제는 그리드 좌표 해상도가 1이다 보니 실제로 인접하지 않은 케이스에서 갈 수 있다고 판단하는 경우가 발생함

예를 들어 (3,5) 좌표와 (3,6)은 실제로는 떨어져 있으나 그리드의 해상도가 1인 경우 인접한 것으로 판단함.
해당 문제는 결국 모든 좌표계를 2배 곱했더니 통과함.






