Cod sursa(job #2767418)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 6 august 2021 01:02:27
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.33 kb
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;

#ifdef INFOARENA
#define ProblemName "barbar"
#endif

#define MCONCAT(A, B) A B
#ifdef ProblemName
#define InFile MCONCAT(ProblemName, ".in")
#define OuFile MCONCAT(ProblemName, ".out")
#else
#define InFile "in"
#define OuFile "out"
#endif

#define MAXN 1100
typedef pair<int, int> square;
#define mp make_pair

char M[MAXN][MAXN];
int R, C;
int prec[MAXN][MAXN];
int dst[MAXN][MAXN];
bool viz[MAXN][MAXN];
int entrance[2], outway[2];
queue<square> Q;

inline char isEmpty(int i, int j) {
	return (M[i][j] != 'D' && M[i][j] != '*');
}

void BFSprec() {
	memset(prec, 0, sizeof(prec));
	memset(viz, 0, sizeof(viz));
	for (int i = 0; i < R; ++i)
		for (int j = 0; j < C; ++j)
			if (M[i][j] == 'D') {
				Q.push(make_pair(i, j));
				viz[i][j] = 1;
			}
	while (!Q.empty()) {
		pair<int, int> t = Q.front();
		Q.pop();
		for (int i = -1; i <= 1; ++i)
			for (int j = -1; j <= 1; ++j) {
				if ((i == 0 && j == 0) || i * j)
					continue;
				int x = t.first + i, y = t.second + j;
				if (x < 0 || x >= R || y < 0 || y >= C)
					continue;
				if (!isEmpty(x, y))
					continue;
				if (viz[x][y])
					continue;
				prec[x][y] = prec[t.first][t.second] + 1;
				viz[x][y] = 1;
				Q.push(make_pair(x, y));
			}
	}
}

char DFS(int t1, int t2, int ans) {
	viz[t1][t2] = 1;
	if (t1 == outway[0] && t2 == outway[1])
		return 1;
	for (int i = -1; i <= 1; ++i)
		for (int j = -1; j <= 1; ++j) {
			if ((i == 0 && j == 0) || i * j)
				continue;
			int x = t1 + i, y = t2 + j;
			if (x < 0 || x >= R || y < 0 || y >= C)
				continue;
			if (!isEmpty(x, y))
				continue;
			if (viz[x][y])
				continue;
			if (prec[x][y] < ans)
				continue;
			if (DFS(x, y, ans))
				return 1;
		}
	return 0;
}

#define QELEM(x,y) mp(dst[x][y], mp(x, y))
int drum[] = { 0, 1, 0, -1, 1, 0, -1, 0 };

void printMat(int a[MAXN][MAXN]) {
	for (int i = 0; i < R; ++i) {
		for (int j = 0; j < C; ++j)
			printf("%d ", dst[i][j]);
		puts("");
	}
}

int solve() {
	BFSprec();
	memset(dst, 0x3F, sizeof dst);
	memset(viz, 0, sizeof viz);
	priority_queue< pair<int, square> > Q;
	dst[entrance[0]][entrance[1]] = prec[entrance[0]][entrance[1]];
	Q.push(QELEM(entrance[0], entrance[1]));
	while (!Q.empty()) {
		auto it = Q.top(); Q.pop();
		int ti = it.second.first, tj = it.second.second;
		int tdst = it.first;
		for (int di = 0; di < 4; ++di) {
			int ni = ti + drum[di * 2], nj = tj + drum[di * 2 + 1];
			if (ni < 0 || ni >= R || nj < 0 || nj >= C) continue;
			if (!isEmpty(ni, nj)) continue;
			int cand = min(dst[ti][tj], prec[ni][nj]);
			if (cand >= dst[ni][nj]) continue;
			if (viz[ni][nj]) continue;
			dst[ni][nj] = cand;
			if (ni == outway[0] && nj == outway[1]) return cand;
			Q.push(QELEM(ni, nj));
			viz[ni][nj] = true;
		}
	}
	if (!viz[outway[0]][outway[1]]) return -1;
	return dst[outway[0]][outway[1]];
}

void readInput() {
	scanf("%d%d", &R, &C);
	for (int i = 0; i < R; ++i)
		for (int j = 0; j < C; ++j) {
			scanf(" %c", &M[i][j]);
			if (M[i][j] == 'I')
				entrance[0] = i, entrance[1] = j;
			else if (M[i][j] == 'O')
				outway[0] = i, outway[1] = j;
		}
}

int main() {
	freopen(InFile, "r", stdin);
	freopen(OuFile, "w", stdout);
	readInput();
	printf("%d\n", solve());
	return 0;
}