Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- mysqld.sock
- 알고리즘 목차
- 영상 프레임 추출
- 백준
- 강의실2
- 알고리즘
- 18249
- 우분투
- 3273
- 탄막 스킬 범위
- 2020 KAKAO BLIND RECRUITMENT
- 마우스 따라다니기
- MySQL
- 탄막
- 문자열 압축
- 3344
- 그리디알고리즘
- 윈도우
- 걷는건귀찮아
- 탄막 이동
- c#
- 원형
- SWEA
- 유니티
- AI Hub
- 자료구조 목차
- 단어 수학
- 토글 그룹
- 회의실 배정
- 수 만들기
Archives
- Today
- Total
와이유스토리
[BFS+DP] 프로그래머스 블록 이동하기 C++ 본문
https://school.programmers.co.kr/learn/courses/30/lessons/60063#
시작 지점 -> 여러 지점 -> 도착 지점
#include <vector>
#include <queue>
using namespace std;
struct Robot {
int x, y, dir, cost;
};
int n;
int dx[4] = {1, 0, -1, 0}; // 시계 방향(우하좌상)
int dy[4] = {0, 1, 0, -1};
int dist[100][100][4]; // 로봇 중심 지점(축) y, x, 다른 지점 방향
vector<vector<int>> Board;
queue<Robot> q;
void check(Robot now, Robot R, bool turn, int x, int y) {
Robot R1 = {R.x, R.y, R.dir, R.cost};
Robot R2 = {R.x + dx[R.dir], R.y + dy[R.dir], (R.dir + 2) % 4, R.cost};
// 로봇 위치
if ((R1.x < 0) || (R1.y < 0) || (R1.x >= n) || (R1.y >= n)) return;
if ((R2.x < 0) || (R2.y < 0) || (R2.x >= n) || (R2.y >= n)) return;
if ((Board[R1.y][R1.x]) ||(Board[R2.y][R2.x])) return;
// 대각선 (bool turn 필요)
if ((turn) && ((x < 0) || (y < 0) || (x >= n) || (y >= n))) return;
if ((turn) && (Board[y][x])) return;
// 로봇의 왼쪽
if (dist[R1.y][R1.x][R1.dir] > dist[now.y][now.x][now.dir] + 1) {
dist[R1.y][R1.x][R1.dir] = dist[now.y][now.x][now.dir] + 1;
q.push({R1.x, R1.y, R1.dir, dist[R1.y][R1.x][R1.dir]});
}
// 로봇의 오른쪽 (반바퀴 차)
now = {now.x + dx[now.dir], now.y + dy[now.dir], (now.dir + 2) % 4, dist[now.y + dy[now.dir]][now.x + dx[now.dir]][(now.dir + 2) % 4]};
if (dist[R2.y][R2.x][R2.dir] > dist[now.y][now.x][now.dir] + 1) {
dist[R2.y][R2.x][R2.dir] = dist[now.y][now.x][now.dir] + 1;
q.push({R2.x, R2.y, R2.dir, dist[R2.y][R2.x][R2.dir]});
}
}
int solution(vector<vector<int>> board) {
n = board.size();
Board = board;
fill(&dist[0][0][0], &dist[n-1][n-1][4], 1e9); // 4차원 시간초과
dist[0][0][0] = dist[0][1][2] = 0;
q.push({0, 0, 0, 0}); // 중심 (0, 0), 나머지 로봇 지점은 0(오른쪽)
q.push({1, 0, 2, 0}); // 중심 (1, 0), 나머지 로봇 지점은 2(왼쪽), x 먼저(TC 5, 11, 12)
while(!q.empty()) {
Robot now = q.front();
q.pop();
if (dist[now.y][now.x][now.dir] < now.cost) continue;
if ((now.x == n-1) && (now.y == n-1)) continue;
if ((now.x + dx[now.dir] == n-1) && (now.y + dy[now.dir] == n-1)) continue;
// 모든 방향으로 로봇 형태 그대로 직진 이동
for(int i=0; i<4; i++) check(now, {now.x+dx[i], now.y+dy[i], now.dir, now.cost}, false, 0, 0);
// 회전 이동
if (now.dir % 2 == 0) { // 가로
check(now, {now.x, now.y, (now.dir + 1) % 4, now.cost}, true, now.x + dx[now.dir], now.y + dy[(now.dir + 1) % 4]); // 시계 방향 90도
check(now, {now.x, now.y, (now.dir + 3) % 4, now.cost}, true, now.x + dx[now.dir], now.y + dy[(now.dir + 3) % 4]); // 시계 반대 방향 90도
}
else { // 세로
check(now, {now.x, now.y, (now.dir + 1) % 4, now.cost}, true, now.x + dx[(now.dir + 1) % 4], now.y + dy[now.dir]); // 시계 방향 90도
check(now, {now.x, now.y, (now.dir + 3) % 4, now.cost}, true, now.x + dx[(now.dir + 3) % 4], now.y + dy[now.dir]); // 시계 반대 방향 90도
}
}
return min(dist[n-1][n-1][2], dist[n-1][n-1][3]);
}
* 시간초과
4차원 배열
#include <vector>
#include <queue>
using namespace std;
struct Robot {
int x1, y1, x2, y2, dir, cnt;
};
int n;
int dist[100][100][100][100];
vector<vector<int>> Board;
queue<Robot> q;
void check(Robot now, Robot R, int x, int y) {
if ((R.x1 < 0) || (R.y1 < 0) || (R.x1 >= n) || (R.y1 >= n)) return;
if ((R.x2 < 0) || (R.y2 < 0) || (R.x2 >= n) || (R.y2 >= n)) return;
if ((x < 0) || (y < 0) || (x >= n) || (y >= n)) return;
if ((Board[y][x]) || (Board[R.y1][R.x1]) ||(Board[R.y2][R.x2])) return;
if (dist[R.y1][R.x1][R.y2][R.x2] < dist[now.y1][now.x1][now.y2][now.x2] + 1) return;
dist[R.y1][R.x1][R.y2][R.x2] = dist[now.y1][now.x1][now.y2][now.x2] + 1;
dist[R.y2][R.x2][R.y1][R.x1] = dist[now.y2][now.x2][now.y1][now.x1] + 1;
R.cnt = dist[R.y1][R.x1][R.y2][R.x2];
q.push(R);
}
int solution(vector<vector<int>> board) {
int d[2] = {-1, 1};
n = board.size();
Board = board;
fill(&dist[0][0][0][0], &dist[n-1][n-1][n-1][n], 1e9); // 4차원 시간초과
dist[0][1][0][0] = 0;
dist[0][0][0][1] = 0;
q.push({0, 0, 1, 0, 0, 0});
while(!q.empty()) {
Robot now = q.front();
q.pop();
if (dist[now.y1][now.x1][now.y2][now.x2] < now.cnt) continue;
if ((now.x1 == n-1) && (now.y1 == n-1)) continue;
if ((now.x2 == n-1) && (now.y2 == n-1)) continue;
for(int i=0; i<2; i++) {
// 모든 방향으로 로봇 형태 그대로 직진
check(now, {now.x1+d[i], now.y1, now.x2+d[i], now.y2, now.dir, now.cnt}, 0, 0);
check(now, {now.x1, now.y1+d[i], now.x2, now.y2+d[i], now.dir, now.cnt}, 0, 0);
// 회전
if (now.dir == 0) { // 가로 방향
check(now, {now.x1, now.y1, now.x1, now.y1+d[i], 1, now.cnt}, now.x2, now.y1+d[i]); // 왼쪽 축
check(now, {now.x2, now.y2, now.x2, now.y2+d[i], 1, now.cnt}, now.x1, now.y2+d[i]); // 오른쪽 축
}
else { // 세로 방향
check(now, {now.x1, now.y1, now.x1+d[i], now.y1, 0, now.cnt}, now.x1+d[i], now.y2); // 위 축
check(now, {now.x2, now.y2, now.x2+d[i], now.y2, 0, now.cnt}, now.x2+d[i], now.y1); // 아래 축
}
}
}
return min(dist[n-1][n-2][n-1][n-1], dist[n-2][n-1][n-1][n-1]);
}
'코딩테스트 > 그래프|트리' 카테고리의 다른 글
[이진 트리] (CHECK) 프로그래머스 길 찾기 게임 C++ (0) | 2023.03.04 |
---|---|
[트리(순회)] (CHECK) 이진 트리, 전위, 중위, 후위, 레벨 순회 및 트리 복원 C++ (0) | 2023.03.01 |
[DFS] 프로그래머스 외벽 점검 C++, Python (0) | 2023.02.26 |
[DFS+BFS+DP, BFS] 프로그래머스 카드 짝 맞추기 C++ (0) | 2023.02.24 |
[그래프(다익스트라), DFS+DP] (CHECK) 프로그래머스 경주로 건설 C++ (0) | 2023.02.21 |
Comments