일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 표현 가능한 이진트리
- Parametric Search
- 방문길이
- try-catch-finally
- 트랜잭션
- synchronized
- 메모리계층구조
- 이펙티브자바
- 자바
- Runtime data area
- 실행과정
- lv3
- multi-thread
- 프로그래머스
- MVCC
- 멀티 프로세스
- 틱택토
- MESI
- java
- 멀티 스레드
- 최장증가부분수열
- try-with-resource
- OS
- 세그멘테이션
- 멀티 코어
- 아키텍처 개선
- 캐시라인
- 이분탐색
- lis
- 함께 자라기
- Today
- Total
siino's 개발톡
[프로그래머스] 아이템 줍기 본문
https://school.programmers.co.kr/learn/courses/30/lessons/87694
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 설명: 여러 직사각형들이 놓여져 있을 때 겹쳐지는 부분을 제외하고 각 변들을 탐색해서 BFS를 수행하는 문제입니다.
제가 생각했던 풀이는 아래와 같습니다.
1. 격자에 각 직사각형들을 색칠한다. (테두리: 1, 내부 -1)
2. 직사각형을 색칠할 때 이미 내부(-1)로 색칠되어 있다면 건너뛴다.
3. 주어진 시작점에서 시작해 색칠된 직사각형들의 1값을 bfs탐색을 통해 주어진 item 좌표로 이동할 때 걸리는 이동거리를 구한다.
하지만 이 부분에서 주의할 점은 다음과 같습니다.
색칠된 테두리의 길이가 1일 때인데요,
위의 그림에서 각 위 로직에 따라 테두리를 빨간색 x표로 표시했습니다.
이때, bfs를 수행하게 되면 화살표로 이동하는 것을 막을 수 없습니다.. 따라서 정답보다 적은 수로 답이 구해지게 됩니다.
이를 방지하기 위한 방법으로 모든 직사각형의 크기를 2배씩 늘리는 방법을 생각할 수 있습니다.
위 그림의 직사각형들의 크기를 각각 2배씩 늘려보면 아래 그림과 같이 되는데요,
이렇게 된다면 위 그림과 같이 해당 화살표에 대한 탐색을 할 일이 없게 됩니다.
따라서 주어진 직사각형들의 좌표를 모두 2배씩 크기를 늘리고 주어진 캐릭터와 아이템의 좌표 또한 2배 하여 나온 답을 2로 나누어 준다면 정답임을 알 수 있습니다.
import java.util.ArrayDeque;
import java.util.Queue;
class Solution {
int[] dx = new int[]{1, 0, -1, 0};
int[] dy = new int[]{0, 1, 0, -1};
public int solution(int[][] rectangle, int characterX, int characterY, int itemX, int itemY) {
int[][] map = new int[101][101];
characterX *= 2;
characterY *= 2;
itemX *= 2;
itemY *= 2;
for(int[] r: rectangle){
r[0] *= 2;
r[1] *= 2;
r[2] *= 2;
r[3] *= 2;
for(int x = r[0]; x <= r[2]; x++){
for(int y = r[1]; y <= r[3]; y++){
//라인일때
if(x == r[0] || x == r[2] || y == r[1] || y == r[3]) {
if(map[x][y] == -1) continue;
map[x][y] = 1;
}
else map[x][y] = -1; //내부 표시
}
}
}
Queue<int[]> queue = new ArrayDeque<>();
boolean[][] visited = new boolean[101][101];
queue.add(new int[]{characterX, characterY, 0}); //좌표 이동거리
visited[characterX][characterY] = true;
while(!queue.isEmpty()){
int[] cur = queue.poll();
if(cur[0] == itemX && cur[1] == itemY) return cur[2] / 2;
for(int dir = 0; dir < 4; dir++){
int nx = cur[0] + dx[dir];
int ny = cur[1] + dy[dir];
if(nx < 0 || ny < 0 || nx >= 101 || ny >= 101) continue;
if(visited[nx][ny] || map[nx][ny] != 1) continue;
queue.add(new int[]{nx, ny, cur[2] + 1});
visited[nx][ny] = true;
}
}
return -1;
}
}
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[2023 KAKAO BLIND RECRUITMENT] 표현 가능한 이진트리 (0) | 2024.03.27 |
---|---|
[프로그래머스] 베스트앨범 - Java (0) | 2024.03.07 |
달리기 경주 - 코틀린 (1) | 2024.02.28 |
[프로그래머스] 혼자서 하는 틱택토 (0) | 2024.02.14 |
[프로그래머스] 입국심사 (1) | 2024.02.07 |