반응형
문제 요약
가로 세로가 최대 500인 맵이 주어진다. 시작점과 도착점이 주어졌을 때, 도착점에 도착이 가능하다면 최단 시간을, 안되면 -1을 출력하면 된다.
풀이
삼성 A형 같은 느낌의 문제다. 문제에서 주어진 조건을 잘 읽고 그대로 구현을 잘해준 다음에 다익스트라를 돌리면 된다.
미끄러졌을 때, 벽으로 가거나 구멍으로 빠지면 그건 움직일 수 없는 경우이다. 조심하자.
돌에 부딪히거나 도착점에 도착해야만 멈추는 게 가능하다.
모든 점 $(i,j)$에 대해서 위, 오른쪽, 아래, 왼쪽으로 쭉 가면서 돌을 만나면 그 지점과 $(i,j)$를 이동에 드는 시간만큼의 간선으로 이어주면 된다.
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 505;
const int MAXM = 505;
const int INF = 1e9;
int N, M;
int board[MAXN][MAXM];
int dy[4] = {-1,0,1,0};
int dx[4] = {0,1,0,-1};
int sy, sx, ty, tx;
vector<vector<pair<int,int>>> G(MAXN*MAXM);
int conv(int y, int x) {
return y*M + x;
}
bool valid(int y, int x) {
return 0<=y && y<N && 0<=x && x<M && board[y][x] != INF;
}
void dijkstra(vector<int> &dist, int src) {
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
dist[src] = 0;
pq.emplace(dist[src], src);
while(!pq.empty()) {
int cur = pq.top().second;
int d = pq.top().first;
pq.pop();
if(dist[cur] < d) continue;
for(pair<int,int> p : G[cur]) {
int v = p.first;
int w = p.second;
if(dist[v] > d + w) {
dist[v] = d + w;
pq.emplace(dist[v], v);
}
}
}
}
int main() {
cin.tie(nullptr); ios::sync_with_stdio(false);
cin >> M >> N;
for(int i=0;i<N;++i) {
string s; cin >> s;
for(int j=0;j<M;++j) {
if(s[j] == 'E') {
ty = i; tx = j;
board[i][j] = 0;
}
else if(s[j] == 'R') {
board[i][j] = -1;
}
else if(s[j] == 'T') {
sy = i; sx = j;
board[i][j] = 0;
}
else if(s[j] == 'H') {
board[i][j] = INF;
}
else board[i][j] = s[j] - '0';
}
}
for(int i=0;i<N;++i) {
for(int j=0;j<M;++j) {
if(i == ty && j == tx) continue;
if(board[i][j] == INF || board[i][j] == -1) continue;
for(int k=0;k<4;++k) {
int y = i, x = j, d = 0;
while(valid(y, x)) {
y += dy[k]; x += dx[k];
if(y == ty && x == tx) break;
if(board[y][x] == -1) {
y -= dy[k]; x -= dx[k];
break;
}
d += board[y][x];
}
if(valid(y, x) && (y != i || x != j)) {
int u = conv(i, j);
int v = conv(y, x);
G[u].emplace_back(v, d);
}
}
}
}
vector<int> dist(MAXN*MAXM, INF);
dijkstra(dist, conv(sy, sx));
if(dist[conv(ty, tx)] == INF) cout << -1 << '\n';
else cout << dist[conv(ty, tx)] << '\n';
return 0;
}
반응형
'Problem Solving > 문제풀이' 카테고리의 다른 글
백준 20938번 반짝반짝 (0) | 2021.03.02 |
---|---|
백준 20927번 Degree Bounded Minimum Spanning Tree (0) | 2021.02.27 |
백준 20925번 메이플스토리 (0) | 2021.02.27 |
백준 20924번 트리의 기둥과 가지 (0) | 2021.02.27 |
백준 20923번 숫자 할리갈리 (0) | 2021.02.27 |