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
- c#
- 알고리즘
- 3344
- 탄막 이동
- 강의실2
- SWEA
- 수 만들기
- 알고리즘 목차
- AI Hub
- 자료구조 목차
- 탄막 스킬 범위
- 문자열 압축
- 그리디알고리즘
- 토글 그룹
- 탄막
- 2020 KAKAO BLIND RECRUITMENT
- 걷는건귀찮아
- 우분투
- 3273
- 윈도우
- 유니티
- 영상 프레임 추출
- 원형
- 18249
- 회의실 배정
- MySQL
- 단어 수학
- 마우스 따라다니기
Archives
- Today
- Total
와이유스토리
[그래프(다익스트라), DFS+DP] (CHECK) 프로그래머스 경주로 건설 C++ 본문
https://school.programmers.co.kr/learn/courses/30/lessons/67259
다익스트라
방향별로 최소 비용 기록
최종 지점 도착할 때까지 어떤 경로가 선택될지 모르기 때문(중간 지점에서 어느 방향이 최소인지 모름)
시작 지점 -> 여러 지점 -> 도착 지점
#include <vector>
#include <queue>
using namespace std;
int N, answer;
vector<vector<int>> Board;
int dx[4] = {0, 0, -1, 1}; // 상하좌우
int dy[4] = {-1, 1, 0, 0};
void dijkstra() {
int dist[N][N][4]; // 방향별로 최소 비용 기록
fill(&dist[0][0][0], &dist[N-1][N-1][4], 1e9);
queue<vector<int>> q;
q.push({0, 0, 0, 1}); // cost, r, c, dir
q.push({0, 0, 0, 3});
while(!q.empty()) {
vector<int> now = q.front();
q.pop();
if (dist[now[1]][now[2]][now[3]] < now[0]) continue;
if ((now[1] == N-1) && (now[2] == N-1)) {
answer = min(answer, now[0]); // return X
continue;
}
for(int i=0; i<4; i++) {
int newX = now[2] + dx[i];
int newY = now[1] + dy[i];
if ((newX < 0) || (newY < 0) || (newX >= N) || (newY >= N)) continue;
if (Board[newY][newX]) continue;
int dir = now[3]; // 이전 방향
int cost = (i == dir)? now[0] + 100 : now[0] + 600; // 방향 전환 여부
if (dist[newY][newX][i] < cost) continue;
dist[newY][newX][i] = cost;
q.push({dist[newY][newX][i], newY, newX, i});
}
}
}
int solution(vector<vector<int>> board) {
answer = 1e9;
N = board.size();
Board = board;
dijkstra();
return answer;
}
DFS+DP
visited 배열 필요 없으나, 있는 것이 속도가 더 빠르다
#include <vector>
using namespace std;
int N, answer;
vector<vector<int>> Board;
bool visited[25][25];
int dist[25][25][4];
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
void dfs(int cost, int r, int c, int dir) {
if ((dir != -1) && (dist[r][c][dir] < cost)) return;
if ((r == N-1) && (c == N-1)) {
answer = min(answer, cost);
return;
}
for(int i=0; i<4; i++) {
int newX = c + dx[i];
int newY = r + dy[i];
if ((newX < 0) || (newY < 0) || (newX >= N) || (newY >= N)) continue;
if (visited[newY][newX]) continue;
if (Board[newY][newX]) continue;
int before = (dir == -1)? i : dir;
int newCost = (i == before)? cost+100 : cost+600;
if (dist[newY][newX][i] < newCost) continue;
visited[newY][newX] = true;
dist[newY][newX][i] = newCost;
dfs(newCost, newY, newX, i);
visited[newY][newX] = false;
}
}
int solution(vector<vector<int>> board) {
answer = 1e9;
N = board.size();
Board = board;
fill(&dist[0][0][0], &dist[N-1][N-1][4], 1e9);
dfs(0, 0, 0, -1);
return answer;
}
BFS+DP
visited 사용하면 dx, dy 순서에 따라 통과되기도 하므로 바람직하지 않다.
따라서 visited 배열 대신 최소 거리를 저장하는 DP 배열이 필요하다.
#include <vector>
#include <queue>
using namespace std;
int N, answer;
vector<vector<int>> Board;
int dx[4] = {0, 0, -1, 1}; // 상하좌우
int dy[4] = {-1, 1, 0, 0};
void bfs() {
int dist[N][N][4];
fill(&dist[0][0][0], &dist[N-1][N-1][4], 1e9);
queue<vector<int>> q;
q.push({0, 0, 0, -1}); // cost, r, c, dir
while(!q.empty()) {
vector<int> now = q.front();
q.pop();
if ((now[3] != -1) && (dist[now[1]][now[2]][now[3]] < now[0])) continue;
if ((now[1] == N-1) && (now[2] == N-1)) {
answer = min(answer, now[0]); // return X
continue;
}
for(int i=0; i<4; i++) {
int newX = now[2] + dx[i];
int newY = now[1] + dy[i];
if ((newX < 0) || (newY < 0) || (newX >= N) || (newY >= N)) continue;
if (Board[newY][newX]) continue;
int dir = (now[3] == -1)? i: now[3]; // 시작점
int cost = (i == dir)? now[0] + 100 : now[0] + 600; // 방향 전환 여부
if (dist[newY][newX][i] < cost) continue;
dist[newY][newX][i] = cost;
q.push({cost, newY, newX, i});
}
}
}
int solution(vector<vector<int>> board) {
answer = 1e9;
N = board.size();
Board = board;
bfs();
return answer;
}
// 시간초과
#include <string>
#include <vector>
#include <queue>
using namespace std;
struct Position {
int x, y, dist, dir;
};
struct cmp {
bool operator()(Position a, Position b) {
return a.dist > b.dist;
}
};
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int solution(vector<vector<int>> board) {
int answer = 0;
int n = board.size();
priority_queue<Position, vector<Position>, cmp> pq;
pq.push({0, 0, 0, 0});
pq.push({0, 0, 0, 1});
while(!pq.empty()) {
Position p = pq.top();
pq.pop();
if ((p.x == n-1) && (p.y == n-1)) {
answer = p.dist;
break;
}
for(int i=0; i<4; i++) {
int newX = p.x + dx[i];
int newY = p.y + dy[i];
if ((newX < 0) || (newY < 0) || (newX >= n) || (newY >= n)) continue;
if (board[newY][newX]) continue;
if (p.dir == i) pq.push({newX, newY, p.dist + 100, i});
else pq.push({newX, newY, p.dist + 600, i});
}
}
return answer;
}
'코딩테스트 > 그래프|트리' 카테고리의 다른 글
[DFS] 프로그래머스 외벽 점검 C++, Python (0) | 2023.02.26 |
---|---|
[DFS+BFS+DP, BFS] 프로그래머스 카드 짝 맞추기 C++ (0) | 2023.02.24 |
[그래프(다익스트라), DP] 프로그래머스 코딩 테스트 공부 C++ (0) | 2023.02.17 |
[그래프(다익스트라)] 프로그래머스 등산코스 정하기 C++ (0) | 2023.02.12 |
[DFS 순열, 그래프, 비트] 프로그래머스 양과 늑대 C++ (0) | 2023.02.11 |
Comments