Muscardinus

스타트 택시 본문

알고리즘 문제/[삼성 SW 역량 테스트 기출 문제]

스타트 택시

Muscardinus 2020. 9. 19. 03:10
728x90

www.acmicpc.net/problem/19238

 

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

'알고리즘 문제 > [삼성 SW 역량 테스트 기출 문제]' 카테고리의 다른 글

큐빙  (0) 2020.09.16
어른상어  (0) 2020.09.15
청소년 상어  (0) 2020.09.11
주사위 윷놀이  (0) 2020.09.06
원판 돌리기  (0) 2020.09.05
Comments