아이템 줍기
프로그래머스 level 3 DFS/BFS
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 설명
지형을 나타내는 직사각형이 담긴 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 이하인 자연수입니다.
- 지형을 나타내는 다각형 테두리 위의 한 점이 주어집니다.
- 캐릭터와 아이템의 처음 위치가 같은 경우는 없습니다.
문제 풀이
사각형의 테두리를 순회해야 하므로,길이를 두배로 늘려서 했다.
init 파트에서 모든 사각형을 칠해주고, 테두리를 제외한 부분만을 남겨줬다.
나머지는 BFS 로 순회하며 길이를 재줬다.
코드
#include <string>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
bool maps[102][102], visited[102][102];
int dis[102][102];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
void init(vector<vector<int>> rectangle) {
for (int i = 0; i < rectangle.size(); i++) {
for (int j = rectangle[i][0] * 2; j <= rectangle[i][2] * 2; j++) {
for (int k = rectangle[i][1] * 2; k <= rectangle[i][3] * 2; k++) {
maps[j][k] = true;
}
}
}
for (int i = 0; i < rectangle.size(); i++) {
for (int j = rectangle[i][0] * 2 + 1; j < rectangle[i][2] * 2; j++) {
for (int k = rectangle[i][1] * 2 + 1; k < rectangle[i][3] * 2; k++) {
maps[j][k] = false;
}
}
}
}
int findItem(int startX, int startY, int eX, int eY) {
queue<pair<int, int>> q;
visited[startX][startY] = true;
q.push(make_pair(startX, startY));
int res;
int x, y, nx, ny;
while (!q.empty()) {
x = q.front().first;
y = q.front().second;
q.pop();
if (x==eX && y==eY) {
res = dis[x][y] / 2;
break;
}
for (int i=0; i<4; i++) {
nx = x + dx[i];
ny = y + dy[i];
if (maps[nx][ny] == 1 && !visited[nx][ny]) {
visited[nx][ny] = true;
dis[nx][ny] = dis[x][y] + 1;
q.push(make_pair(nx, ny));
}
}
}
return res;
}
int solution(vector<vector<int>> rectangle, int characterX, int characterY, int itemX, int itemY) {
int answer = 0;
memset(visited, false, sizeof(visited));
memset(maps, false, sizeof(maps));
memset(dis, 0, sizeof(dis));
init(rectangle);
return findItem(characterX*2, characterY*2, itemX*2, itemY*2);
}
회고
예전에 풀다가 포기한 문제였다.
초기활 할 때, 직사각형을 두배 해 놓는 테크닉을 기억해 놔야 할듯.
이번에는 예전에 해놓은 코드를 보고 살짝만 수정해서 답을 놨다.
'ps' 카테고리의 다른 글
99클럽 코테스터디 34일차 TIL 프로그래머스- 여행경로 (0) | 2024.08.24 |
---|---|
99클럽 코테스터디 33일차 TIL 프로그래머스- 단어 변환 (0) | 2024.08.23 |
99클럽 코테스터디 31일차 TIL 프로그래머스- 네트워크 (0) | 2024.08.21 |
99클럽 코테스터디 30일차 TIL LeetCode - Minimum Operations to Make a Subsequence (0) | 2024.08.20 |
99클럽 코테스터디 29일차 TIL LeetCode - Maximum Profit in Job Scheduling (0) | 2024.08.19 |