Muscardinus
스타트 택시 본문
728x90
19238번: 스타트 택시
첫 줄에 N, M, 그리고 초기 연료의 양이 주어진다. (2 ≤ N ≤ 20, 1 ≤ M ≤ N2, 1 ≤ 초기 연료 ≤ 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다
www.acmicpc.net
#include <iostream>
#include <queue>
using namespace std;
struct CUSTOMER {
int start, end;
};
struct TAXI {
int pos, distance;
};
const int WALL = -1;
const int EMPTY = -2;
const int dy[] = { 0,0,1,-1 };
const int dx[] = { -1,1,0,0 };
int n, m, fuel;
int taxi_y, taxi_x;
int board[20][20];
CUSTOMER customer[400];
int find_customer() {
queue<TAXI> q;
bool visited[20][20] = { false, };
TAXI cur = { taxi_y * 100 + taxi_x, 0 };
visited[taxi_y][taxi_x] = true;
q.push(cur);
int candi_size = 0;
int candi[400] = { 0, };
int candi_distance = -1;
while (!q.empty()) {
cur = q.front();
q.pop();
if (candi_distance != -1 && cur.distance > candi_distance) break;
int y = cur.pos / 100;
int x = cur.pos % 100;
if (board[y][x] >= 0) {
candi[candi_size++] = board[y][x];
candi_distance = cur.distance;
}
for (int d = 0; d < 4; d++) {
int ny = y + dy[d];
int nx = x + dx[d];
if (ny < 0 || ny >= n || nx < 0 || nx >= n || board[ny][nx] == WALL || visited[ny][nx] == true) continue;
visited[ny][nx] = true;
TAXI next = { ny * 100 + nx, cur.distance + 1 };
q.push(next);
}
}
if (candi_distance > fuel) return -1;
int ret = -1;
int candi_val = 2147000000;
for (int i = 0; i < candi_size; i++) {
if (candi_val > customer[candi[i]].start) {
candi_val = customer[candi[i]].start;
ret = candi[i];
}
}
taxi_y = customer[ret].start / 100;
taxi_x = customer[ret].start % 100;
board[taxi_y][taxi_x] = EMPTY;
fuel -= candi_distance;
return ret;
}
bool move_customer(int target) {
queue<TAXI> q;
bool visited[20][20] = { false, };
TAXI cur = { taxi_y * 100 + taxi_x, 0 };
visited[taxi_y][taxi_x] = true;
q.push(cur);
while (!q.empty()) {
cur = q.front();
q.pop();
if (cur.distance > fuel) return false;
if (cur.pos == customer[target].end) {
taxi_y = customer[target].end / 100;
taxi_x = customer[target].end % 100;
fuel += cur.distance;
return true;
}
int y = cur.pos / 100;
int x = cur.pos % 100;
for (int d = 0; d < 4; d++) {
int ny = y + dy[d];
int nx = x + dx[d];
if (ny < 0 || ny >= n || nx < 0 || nx >= n || board[ny][nx] == WALL || visited[ny][nx] == true) continue;
TAXI next = { ny * 100 + nx, cur.distance + 1 };
q.push(next);
visited[ny][nx] = true;
}
}
return false;
}
int solve() {
int ret = -1;
for (int i = 0; i < m; i++) {
int target = find_customer();
if (target == -1) return ret;
bool success = move_customer(target);
if (success == false) return ret;
}
ret = fuel;
return ret;
}
int main() {
ios_base::sync_with_stdio(false);
cin >> n >> m >> fuel;
for (int y = 0; y < n; y++) {
for (int x = 0; x < n; x++) {
cin >> board[y][x];
board[y][x] -= 2;
}
}
cin >> taxi_y >> taxi_x;
taxi_y--; taxi_x--;
for (int i = 0; i < m; i++) {
int sy, sx, ey, ex;
cin >> sy >> sx >> ey >> ex;
sy--; sx--; ey--; ex--;
customer[i].start = (sy * 100 + sx);
customer[i].end = (ey * 100 + ex);
board[sy][sx] = i;
}
int ret = solve();
cout << ret << "\n";
return 0;
}
728x90
Comments