728x90
https://programmers.co.kr/learn/courses/30/lessons/87694
코딩테스트 연습 - 11주차
[[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 [[2,2,5,5],[1,3,6,4],[3,1,4,6]] 1 4 6 3 10
programmers.co.kr
문제 풀이
import java.util.*;
public class Solution {
class Position {
int x, y, m;
public Position(int x, int y, int m) {
this.x = x;
this.y = y;
this.m = m;
}
}
public int solution(int[][] rectangle, int characterX, int characterY, int itemX, int itemY) {
int xs, ys, xe, ye, x_max, y_max; x_max = y_max = 0;
int n = rectangle.length, r[], i, j, k;
for (i = 0; i < n; ++i) {
r = rectangle[i];
for (j = 0; j < 4; ++j) r[j] *= 2;
xe = r[2]; ye = r[3];
x_max = x_max < xe ? xe : x_max;
y_max = y_max < ye ? ye : y_max;
}
int w = y_max + 1, h = x_max + 1;
boolean t[][] = new boolean[h][w];
for (i = 0; i < n; ++i) {
r = rectangle[i];
xs = r[0]; ys = r[1]; xe = r[2]; ye = r[3];
for (j = xs + 1; j < xe; ++j)
for (k = ys + 1; k < ye; ++k)
t[j][k] = true;
}
boolean b[][] = new boolean[h][w];
for (i = 0; i < n; ++i) {
r = rectangle[i];
xs = r[0]; ys = r[1]; xe = r[2]; ye = r[3];
for (j = ys; j <= ye; ++j) {
if (!t[xs][j]) b[xs][j] = true;
if (!t[xe][j]) b[xe][j] = true;
}
for (j = xs; j <= xe; ++j) {
if (!t[j][ys]) b[j][ys] = true;
if (!t[j][ye]) b[j][ye] = true;
}
}
int xc = characterX * 2, yc = characterY * 2, xi = itemX * 2, yi = itemY * 2;
int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0}, d, x, y, m, nx, ny, nm;
Queue<Position> q = new ArrayDeque<>(); Position p;
boolean v[][] = new boolean[h][w];
q.add(new Position(xc, yc, 0));
v[xc][yc] = true;
while (!q.isEmpty()) {
p = q.remove();
x = p.x; y = p.y; m = p.m;
for (d = 0; d < 4; ++d) {
nx = x + dx[d]; ny = y + dy[d];
if (nx < 0 || nx >= h || ny < 0 || ny >= w || !b[nx][ny] || v[nx][ny])
continue;
nm = m + 1;
if (nx == xi && ny == yi) return nm / 2;
q.add(new Position(nx, ny, nm));
v[nx][ny] = true;
}
}
return 0;
}
}
예제 1를 대표로 설명
- 입력받은 int[][] rectangle 배열을 순회하며 각 좌표값을 2배로 늘림
( 좌표나 배열에서 한 정사각형을 기준으로,
좌표는 정사각형의 모서리(교점) 한 점을 기준으로 보는 것이고 배열은 정사각형 그 자체이므로
배열에서 정사각형 한 칸을 좌표의 한 점으로 취급 )
- boolean t[][] 생성하여 한 직사각형의 테두리를 제외한 부분에 true 값을 대입
- boolean b[][] 생성하여 한 직사각형의 테두리에만 true 값을 대입하되,
그 위치( x, y )가 직사각형의 안에 있는 경우( t[x][y] == true )는 제외
- 캐릭터가 위치한 좌표( int xc, yc ), 아이템이 위치한 좌표( int xi, yi ) 역시 x, y 좌표값을 각각 두 배로 늘림
- 캐릭터가 위치한 좌표를 시작점으로 하여, BFS 하면서 이동 횟수를 세다가 아이템이 위치한 좌표에 도착하면 종료 후 횟수/2 한 값을 리턴
반응형
'코딩 문제 풀기 ( Algorithm problem solving ) > 프로그래머스 ( Programmers )' 카테고리의 다른 글
[프로그래머스(Programmers)][자바(java)] (Lv4) 올바른 괄호의 개수 (0) | 2021.10.28 |
---|---|
[프로그래머스(Programmers)][자바(java)] (Lv2) 12주차 - 피로도 <위클리 챌린지> (0) | 2021.10.26 |
[프로그래머스(Programmers)][자바(java)] (Lv2) n^2 배열 자르기 <월간코드챌린지3> (0) | 2021.10.16 |
[프로그래머스(Programmers)][자바(java)] (Lv1) 나머지가 1이 되는 수 찾기 <월간코드챌린지3> (0) | 2021.10.16 |
[프로그래머스(Programmers)][자바(java)] (Lv2) 10주차 - 교점에 별 만들기 <위클리 챌린지> (0) | 2021.10.13 |