Submission #1343551

#TimeUsernameProblemLanguageResultExecution timeMemory
1343551yuqziiPortals (BOI14_portals)C++20
100 / 100
461 ms135396 KiB
#include <bits/stdc++.h>

using namespace std;

int r, c;

int posToID(int i, int j) {
	return c*i + j;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> r >> c;
	int start = 0, target = 0;
	vector<vector<char>> a(r, vector<char>(c));
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			cin >> a[i][j];
			if (a[i][j] == 'S')
				start = posToID(i, j);
			else if (a[i][j] == 'C')
				target = posToID(i, j);
		}
	}
	
	vector<vector<int>> preR(r, vector<int>(c)), preC(c, vector<int>(r));
	for (int i = 0; i < r; i++)
		preR[i][0] = a[i][0] == '#';
	for (int j = 0; j < c; j++)
		preC[j][0] = a[0][j] == '#';

	for (int i = 0; i < r; i++)
		for (int j = 1; j < c; j++)
			preR[i][j] = preR[i][j-1] + (a[i][j] == '#');
	for (int i = 1; i < r; i++)
		for (int j = 0; j < c; j++)
			preC[j][i] = preC[j][i-1] + (a[i][j] == '#');

	vector<int> wDist(r * c, -1);
	queue<tuple<int, int, int>> q;
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			if (a[i][j] == '#') q.emplace(i, j, 0);
		}
	}
	for (int i = 0; i < r; i++) {
		if (a[i][0] != '#') q.emplace(i, 0, 1);
		if (a[i][c-1] != '#') q.emplace(i, c-1, 1);
	}
	for (int j = 0; j < c; j++) {
		if (a[0][j] != '#') q.emplace(0, j, 1);
		if (a[r-1][j] != '#') q.emplace(r-1, j, 1);
	}
	while (!q.empty()) {
		auto [i, j, d] = q.front();
		q.pop();
		if (i < 0 || i >= r || j < 0 || j >= c) continue;
		int u = posToID(i, j);
		if (wDist[u] != -1) continue;

		wDist[u] = d;
		q.emplace(i+1, j, d+1);
		q.emplace(i-1, j, d+1);
		q.emplace(i, j+1, d+1);
		q.emplace(i, j-1, d+1);
	}

	vector<vector<pair<int, int>>> adj(r * c);
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			if (a[i][j] == '#') continue;

			int u = posToID(i, j);
			if (i > 0 && a[i-1][j] != '#') adj[u].emplace_back(posToID(i-1, j), 1);
			if (i < r - 1 && a[i+1][j] != '#') adj[u].emplace_back(posToID(i+1, j), 1);
			if (j > 0 && a[i][j-1] != '#') adj[u].emplace_back(posToID(i, j-1), 1);
			if (j < c - 1 && a[i][j+1] != '#') adj[u].emplace_back(posToID(i, j+1), 1);

			int pLeft = (preR[i][j] == 0)
				? 0
				: lower_bound(preR[i].begin(), preR[i].end(), preR[i][j]) - preR[i].begin() + 1;
			int pRight = upper_bound(preR[i].begin(), preR[i].end(), preR[i][j]) - preR[i].begin() - 1;
			int pUp = (preC[j][i] == 0)
				? 0
				: lower_bound(preC[j].begin(), preC[j].end(), preC[j][i]) - preC[j].begin() + 1;
			int pDown = upper_bound(preC[j].begin(), preC[j].end(), preC[j][i]) - preC[j].begin() - 1;

			adj[u].emplace_back(posToID(i, pLeft), wDist[u]);
			adj[u].emplace_back(posToID(i, pRight), wDist[u]);
			adj[u].emplace_back(posToID(pUp, j), wDist[u]);
			adj[u].emplace_back(posToID(pDown, j), wDist[u]);
		}
	}

	vector<int> dist(r * c, -1);
	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
	pq.emplace(0, start);
	while (!pq.empty()) {
		auto [d, u] = pq.top();
		pq.pop();
		if (dist[u] != -1) continue;

		if (u == target) {
			cout << d << '\n';
			return 0;
		}

		dist[u] = d;
		for (auto [v, w] : adj[u]) {
			if (dist[v] != -1) continue;
			pq.emplace(d + w, v);
		}
	}

	cout << "oops\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...