#include <iostream>
#include <vector>
#include <memory.h>
#include <queue>
#include <algorithm>
using namespace std;
int N, M, fuel;
int minX, minY, minDist;
int board[21][21] = { 0, }; // 길(0), 벽(1), 승객(2)
int dx[4] = { -1, 1, 0, 0 };
int dy[4] = { 0, 0, -1, 1 };
int taxiX, taxiY;
vector<pair<int, int>> passengers;
vector<pair<int, int>> destinations;
int arrived[400] = { 0, };
// 현재 택시 위치에서 가장 가까운 승객을 찾는 완전탐색
void findNearPassenger() {
minX = 100, minY = 100, minDist = 400;
bool visited[21][21];
int dist[21][21]; // 시작점에서 거리 정보
memset(dist, 0, sizeof(dist));
memset(visited, false, sizeof(visited));
queue<pair<int, int>> q;
q.push(make_pair(taxiX, taxiY));
visited[taxiX][taxiY] = true;
dist[taxiX][taxiY] = 0;
while (!q.empty()) {
pair<int, int> cpos = q.front();
q.pop();
for (int dir = 0; dir < 4; dir++) {
int nextX = cpos.first + dx[dir];
int nextY = cpos.second + dy[dir];
if (nextX < 1 || nextX > N || nextY < 1 || nextY > N) continue;
if (board[nextX][nextY] == 1) continue;
if (visited[nextX][nextY]) continue;
visited[nextX][nextY] = true;
q.push(make_pair(nextX, nextY));
dist[nextX][nextY] = dist[cpos.first][cpos.second] + 1;
if (board[nextX][nextY] == 2) { // 승객인 경우
if (minDist > dist[nextX][nextY]) {
minDist = dist[nextX][nextY];
minX = nextX;
minY = nextY;
}
else if (minDist == dist[nextX][nextY]) {
if (minX > nextX) {
minX = nextX;
minY = nextY;
}
else if (minX == nextX) {
if (minY > nextY) {
minX = nextX;
minY = nextY;
}
}
}
}
}
}
}
int getDistToDestination(int index) {
bool visited[21][21];
int dist[21][21];
int x = passengers[index].first;
int y = passengers[index].second;
int destX = destinations[index].first;
int destY = destinations[index].second;
memset(dist, 0, sizeof(dist));
memset(visited, false, sizeof(visited));
queue<pair<int, int>> q;
q.push(make_pair(x, y));
visited[x][y] = true;
while (!q.empty()) {
pair<int, int> cpos = q.front();
q.pop();
for (int dir = 0; dir < 4; dir++) {
int nextX = cpos.first + dx[dir];
int nextY = cpos.second + dy[dir];
if (nextX < 1 || nextX > N || nextY < 1 || nextY > N) continue;
if (board[nextX][nextY] == 1) continue;
if (visited[nextX][nextY]) continue;
visited[nextX][nextY] = true;
dist[nextX][nextY] = dist[cpos.first][cpos.second] + 1;
q.push(make_pair(nextX, nextY));
if (nextX == destX && nextY == destY)
return dist[destX][destY];
}
}
return dist[destX][destY];
}
int getIndexPassenger() {
for (int i = 0; i < M; i++) {
if (arrived[i] == 1) continue;
if (passengers[i].first == minX && passengers[i].second == minY) {
return i;
}
}
return -1;
}
void takeOffTaxi() {
int cnt = 0;
int idx = -1;
// update distance info
vector<int> distInfo;
int val;
for (int i = 0; i < M; i++) {
val = getDistToDestination(i);
distInfo.push_back(val);
}
while (true) {
// printf("%d\n", fuel);
if (cnt == M) break;
if (board[taxiX][taxiY] == 2) {
minX = taxiX;
minY = taxiY;
minDist = 0;
}
else
findNearPassenger(); // 가까운 승객 찾기
if (minX == 100 && minY == 100) { // 접근이 불가능한 경우
printf("-1\n");
return;
}
idx = getIndexPassenger();
arrived[idx] = 1;
fuel -= minDist; // 택시 -> 승객
fuel -= distInfo[idx]; // 승객 -> 목적지
if (distInfo[idx] == 0) {
printf("-1\n");
return;
}
if (fuel < 0) {
printf("-1\n");
return;
}
fuel += (distInfo[idx] * 2);
cnt++;
taxiX = destinations[idx].first;
taxiY = destinations[idx].second;
board[minX][minY] = 0;
}
printf("%d\n", fuel);
}
int main()
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
scanf("%d %d %d", &N, &M, &fuel);
for (int r = 1; r <= N; r++) {
for (int c = 1; c <= N; c++) {
scanf("%d", &board[r][c]);
}
}
scanf("%d %d", &taxiX, &taxiY);
for (int i = 0; i < M; i++) {
int x, y, fx, fy;
scanf("%d %d %d %d", &x, &y, &fx, &fy);
passengers.push_back(make_pair(x, y));
destinations.push_back(make_pair(fx, fy));
board[x][y] = 2;
}
takeOffTaxi();
return 0;
}
Leave a comment