반응형

https://www.acmicpc.net/problem/19238

 

19238번: 스타트 택시

첫 줄에 N, M, 그리고 초기 연료의 양이 주어진다. (2 ≤ N ≤ 20, 1 ≤ M ≤ N2, 1 ≤ 초기 연료 ≤ 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다

www.acmicpc.net

 

몇 가지 예외사항을 잘 신경써줘야했습니다.

"모든 출발지는 서로 다르며, 각 손님의 출발지와 목적지는 다르다."

즉, 각 손님의 출발지는 다르지만, 목적지는 같을 수 있습니다.

따라서 출발지는 기존의 지도 위에 표현해도 되었지만, 목적지는 손님의 번호를 붙여서 별도로 기억해줘야 했습니다.

연료는 손님을 태운 시점부터 도착지까지의 이동거리의 두 배가 늘어나게 됩니다.

최단 거리의 승객이 여러 명일 때, (행 번호, 열 번호)가 더 작은 승객을 선택해줘야 합니다.

 

#include <iostream>
#include <queue>
#include <unordered_map>
#define INF 2147483647
using namespace std;

int dx[] = { -1,0,0,1 };
int dy[] = { 0,-1,1,0 };

int n, m, k, tx, ty, a, b, c, d, cnt = 0, v = 1;
int map[21][21] = { 0 };
int visit[21][21] = { 0 };
unordered_map<int, pair<int, int>> dest;

vector<int> filterGuest(vector<vector<int>>& finded) {
	int fg = finded[0][0], fx = finded[0][1], fy = finded[0][2];
	for (int i = 1; i < finded.size(); i++) {
		int g = finded[i][0], x = finded[i][1], y = finded[i][2];
		if (x < fx) {
			fg = g, fx = x, fy = y;
		}
		else if (x == fx) {
			if (y < fy) {
				fg = g, fx = x, fy = y;
			}
		}
	}
	return { fg, fx, fy };
}

vector<int> pickUpGuest() {
	v++;
	vector<vector<int>> finded;
	int dist = INF;
	queue<vector<int>> q;
	q.push({ tx, ty, 0 });
	visit[tx][ty] = v;
	while (!q.empty()) {
		int x = q.front()[0];
		int y = q.front()[1];
		int g = q.front()[2];
		q.pop();
		if (map[x][y] < 0) {
			if (k >= g && dist >= g) {
				finded.push_back({ -map[x][y], x, y });
				dist = g;
			}
		}
		for (int i = 0; i < 4; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			if (nx < 1 || ny < 1 || nx > n || ny > n || visit[nx][ny] == v || map[nx][ny] == 1) continue;
			q.push({ nx, ny, g + 1 });
			visit[nx][ny] = v;
		}
	}
	if (finded.size() == 0) return { -1 };
	vector<int> filteredGuest = filterGuest(finded);
	map[filteredGuest[1]][filteredGuest[2]] = 0;
	k -= dist;
	return filteredGuest;
}

pair<int, int> findDest(int guest) {
	return dest[guest];
}

vector<int> dropGuest(int guest) {
	v++;
	pair<int, int> d = findDest(guest);
	queue<vector<int>> q;
	q.push({ tx, ty, 0 });
	visit[tx][ty] = v;
	while (!q.empty()) {
		int x = q.front()[0];
		int y = q.front()[1];
		int g = q.front()[2];
		q.pop();
		if (x == d.first && y == d.second) {
			if (k >= g) {
				k -= g;
				k += 2 * g;
				return { x, y };
			}
			break;
		}
		for (int i = 0; i < 4; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			if (nx < 1 || ny < 1 || nx > n || ny > n || visit[nx][ny] == v || map[nx][ny] == 1) continue;
			q.push({ nx, ny, g + 1 });
			visit[nx][ny] = v;
		}
	}
	return { -1, -1 };
}

int main() {
	scanf("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			scanf("%d", &map[i][j]);
		}
	}

	scanf("%d %d", &tx, &ty);
	for (int i = 1; i <= m; i++) {
		scanf("%d %d %d %d", &a, &b, &c, &d);
		map[a][b] = -i;
		dest.insert({ i, {c, d} });
	}

	while (cnt < m) {
		vector<int> pPos = pickUpGuest();
		if (pPos[0] == -1) break;
		tx = pPos[1], ty = pPos[2];
		vector<int> dPos = dropGuest(pPos[0]);
		if (dPos[0] == -1) break;
		tx = dPos[0], ty = dPos[1];
		cnt++;
	}
	printf("%d", cnt == m ? k : -1);
}
반응형

'Algorithm' 카테고리의 다른 글

백준 2533 : 사회망 서비스(SNS)  (0) 2021.11.17
백준 2800 : 괄호 제거  (0) 2021.11.17
백준 16120 : PPAP  (0) 2021.11.17
백준 7490 : 0 만들기  (0) 2021.11.17
백준 1005 : ACM Craft  (0) 2021.11.17

+ Recent posts