πŸ™‡β€β™€οΈ[Gold V] ν† λ§ˆν†  - 7569

문제 링크

μ„±λŠ₯ μš”μ•½

λ©”λͺ¨λ¦¬: 12368 KB, μ‹œκ°„: 132 ms

λΆ„λ₯˜

λ„ˆλΉ„ μš°μ„  탐색, κ·Έλž˜ν”„ 이둠, κ·Έλž˜ν”„ 탐색

제좜 일자

2024λ…„ 1μ›” 12일 12:42:17

문제 μ„€λͺ…

철수의 ν† λ§ˆν†  농μž₯μ—μ„œλŠ” ν† λ§ˆν† λ₯Ό λ³΄κ΄€ν•˜λŠ” 큰 μ°½κ³ λ₯Ό 가지고 μžˆλ‹€. ν† λ§ˆν† λŠ” μ•„λž˜μ˜ κ·Έλ¦Όκ³Ό 같이 격자λͺ¨μ–‘ μƒμžμ˜ 칸에 ν•˜λ‚˜μ”© 넣은 λ‹€μŒ, μƒμžλ“€μ„ 수직으둜 μŒ“μ•„ μ˜¬λ €μ„œ 창고에 λ³΄κ΄€ν•œλ‹€.

창고에 λ³΄κ΄€λ˜λŠ” ν† λ§ˆν† λ“€ μ€‘μ—λŠ” 잘 읡은 것도 μžˆμ§€λ§Œ, 아직 읡지 μ•Šμ€ ν† λ§ˆν† λ“€λ„ μžˆμ„ 수 μžˆλ‹€. 보관 ν›„ ν•˜λ£¨κ°€ μ§€λ‚˜λ©΄, 읡은 ν† λ§ˆν† λ“€μ˜ μΈμ ‘ν•œ 곳에 μžˆλŠ” 읡지 μ•Šμ€ ν† λ§ˆν† λ“€μ€ 읡은 ν† λ§ˆν† μ˜ 영ν–₯을 λ°›μ•„ 읡게 λœλ‹€. ν•˜λ‚˜μ˜ ν† λ§ˆν† μ— μΈμ ‘ν•œ 곳은 μœ„, μ•„λž˜, μ™Όμͺ½, 였λ₯Έμͺ½, μ•ž, λ’€ μ—¬μ„― λ°©ν–₯에 μžˆλŠ” ν† λ§ˆν† λ₯Ό μ˜λ―Έν•œλ‹€. λŒ€κ°μ„  λ°©ν–₯에 μžˆλŠ” ν† λ§ˆν† λ“€μ—κ²ŒλŠ” 영ν–₯을 주지 λͺ»ν•˜λ©°, ν† λ§ˆν† κ°€ 혼자 μ €μ ˆλ‘œ μ΅λŠ” κ²½μš°λŠ” μ—†λ‹€κ³  κ°€μ •ν•œλ‹€. μ² μˆ˜λŠ” 창고에 λ³΄κ΄€λœ ν† λ§ˆν† λ“€μ΄ 며칠이 μ§€λ‚˜λ©΄ λ‹€ 읡게 λ˜λŠ”μ§€ κ·Έ μ΅œμ†Œ 일수λ₯Ό μ•Œκ³  μ‹Άμ–΄ ν•œλ‹€.

ν† λ§ˆν† λ₯Ό 창고에 λ³΄κ΄€ν•˜λŠ” 격자λͺ¨μ–‘μ˜ μƒμžλ“€μ˜ 크기와 읡은 ν† λ§ˆν† λ“€κ³Ό 읡지 μ•Šμ€ ν† λ§ˆν† λ“€μ˜ 정보가 μ£Όμ–΄μ‘Œμ„ λ•Œ, 며칠이 μ§€λ‚˜λ©΄ ν† λ§ˆν† λ“€μ΄ λͺ¨λ‘ μ΅λŠ”μ§€, κ·Έ μ΅œμ†Œ 일수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λΌ. 단, μƒμžμ˜ 일뢀 μΉΈμ—λŠ” ν† λ§ˆν† κ°€ λ“€μ–΄μžˆμ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€.

μž…λ ₯

첫 μ€„μ—λŠ” μƒμžμ˜ 크기λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 두 μ •μˆ˜ M,Nκ³Ό μŒ“μ•„μ˜¬λ €μ§€λŠ” μƒμžμ˜ 수λ₯Ό λ‚˜νƒ€λ‚΄λŠ” Hκ°€ 주어진닀. M은 μƒμžμ˜ κ°€λ‘œ 칸의 수, N은 μƒμžμ˜ μ„Έλ‘œ 칸의 수λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 단, 2 ≀ M ≀ 100, 2 ≀ N ≀ 100, 1 ≀ H ≀ 100 이닀. λ‘˜μ§Έ μ€„λΆ€ν„°λŠ” κ°€μž₯ λ°‘μ˜ μƒμžλΆ€ν„° κ°€μž₯ μœ„μ˜ μƒμžκΉŒμ§€μ— μ €μž₯된 ν† λ§ˆν† λ“€μ˜ 정보가 주어진닀. 즉, λ‘˜μ§Έ 쀄뢀터 N개의 μ€„μ—λŠ” ν•˜λ‚˜μ˜ μƒμžμ— λ‹΄κΈ΄ ν† λ§ˆν† μ˜ 정보가 주어진닀. 각 μ€„μ—λŠ” μƒμž κ°€λ‘œμ€„μ— λ“€μ–΄μžˆλŠ” ν† λ§ˆν† λ“€μ˜ μƒνƒœκ°€ M개의 μ •μˆ˜λ‘œ 주어진닀. μ •μˆ˜ 1은 읡은 ν† λ§ˆν† , μ •μˆ˜ 0 은 읡지 μ•Šμ€ ν† λ§ˆν† , μ •μˆ˜ -1은 ν† λ§ˆν† κ°€ λ“€μ–΄μžˆμ§€ μ•Šμ€ 칸을 λ‚˜νƒ€λ‚Έλ‹€. μ΄λŸ¬ν•œ N개의 쀄이 H번 λ°˜λ³΅ν•˜μ—¬ 주어진닀.

ν† λ§ˆν† κ°€ ν•˜λ‚˜ 이상 μžˆλŠ” 경우만 μž…λ ₯으둜 주어진닀.

좜λ ₯

μ—¬λŸ¬λΆ„μ€ ν† λ§ˆν† κ°€ λͺ¨λ‘ 읡을 λ•ŒκΉŒμ§€ μ΅œμ†Œ 며칠이 κ±Έλ¦¬λŠ”μ§€λ₯Ό κ³„μ‚°ν•΄μ„œ 좜λ ₯ν•΄μ•Ό ν•œλ‹€. λ§Œμ•½, μ €μž₯될 λ•ŒλΆ€ν„° λͺ¨λ“  ν† λ§ˆν† κ°€ μ΅μ–΄μžˆλŠ” μƒνƒœμ΄λ©΄ 0을 좜λ ₯ν•΄μ•Ό ν•˜κ³ , ν† λ§ˆν† κ°€ λͺ¨λ‘ μ΅μ§€λŠ” λͺ»ν•˜λŠ” 상황이면 -1을 좜λ ₯ν•΄μ•Ό ν•œλ‹€.

πŸš€ν’€μ΄

BFS문제둜 이전에 ν’€μ—ˆλ˜ 방식을 κ·ΈλŒ€λ‘œ μ‚¬μš©ν•˜λ©΄ λœλ‹€.

이전엔 dis배열을 λ§Œλ“€μ–΄μ„œ ν–ˆλŠ”λ° μ΄λ²ˆμ—” discovered배열을 λ§Œλ“€μ–΄μ„œ 발견과 거리λ₯Ό λ™μ‹œμ— κ³„μ‚°ν–ˆλ‹€.

int dy[] = { -1, 0, 1, 0, 0, 0 };
int dx[] = { 0, 1, 0, -1, 0, 0 };
int dz[] = { 0, 0, 0, 0, 1, -1 };
void solve()
{
	//discovered[z][y][x] = 1;

	while (q.empty() == false)
	{
		Pos here = q.front();
		q.pop();

		for (int i = 0; i < 6; ++i)
		{
			int nz = here.z + dz[i];
			int ny = here.y + dy[i];
			int nx = here.x + dx[i];

			if (nz < 1 || ny < 1 || nx < 1 || nz > h || ny > n || nx > m)
				continue;
			if (discovered[nz][ny][nx] >= 1)
				continue;
			if (board[nz][ny][nx] == -1)
				continue;
			if (board[nz][ny][nx] == 1)
				continue;
			
			discovered[nz][ny][nx] = discovered[here.z][here.y][here.x] + 1;
			q.push({ nz, ny, nx });
		}
	}

	//for (int i = 1; i <= h; ++i)
	//{
	//	for (int j = 1; j <= n; ++j)
	//	{
	//		for (int k = 1; k <= m; ++k)
	//		{
	//			cout << discovered[i][j][k];
	//		}
	//		cout << endl;
	//	}
	//}

	bool flag = false;
	int res = 0;
	for (int i = 1; i <= h; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			for (int k = 1; k <= m; ++k)
			{
				if (discovered[i][j][k] == 0 && board[i][j][k] != -1)
				{
					flag = true;
					cout << -1 << '\n';
					return;
				}

				res = max(res, discovered[i][j][k]);
			}
		}
	}

	cout << res - 1;
}

3차원 κ³΅κ°„μ΄λ―€λ‘œ dx, dy, dzλ₯Ό λ§Œλ“€μ–΄μ„œ ν’€μ—ˆλ‹€.

주석은 κ²°κ³Όλ₯Ό 보고 μ‹Άμ–΄μ„œ 넣은 μ½”λ“œμ΄λ‹€.

πŸš€μ „μ²΄ μ½”λ“œ

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include<iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct Pos
{
	int z, y, x;
};

int m, n, h;
vector<vector<vector<int>>> board;
vector<vector<vector<int>>> discovered;
queue<Pos> q;
void setting()
{
	cin >> m >> n >> h;
	board = vector<vector<vector<int>>>(h + 1, vector<vector<int>>(n + 1, vector<int>(m + 1)));
	discovered = vector<vector<vector<int>>>(h + 1, vector<vector<int>>(n + 1, vector<int>(m + 1)));

	for (int i = 1; i <= h; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			for (int k = 1; k <= m; ++k)
			{
				cin >> board[i][j][k];
				if (board[i][j][k] == 1)
				{
					q.push({ i, j, k });
					discovered[i][j][k] = 1;
				}
			}
		}
	}
}

int dy[] = { -1, 0, 1, 0, 0, 0 };
int dx[] = { 0, 1, 0, -1, 0, 0 };
int dz[] = { 0, 0, 0, 0, 1, -1 };
void solve()
{
	//discovered[z][y][x] = 1;

	while (q.empty() == false)
	{
		Pos here = q.front();
		q.pop();

		for (int i = 0; i < 6; ++i)
		{
			int nz = here.z + dz[i];
			int ny = here.y + dy[i];
			int nx = here.x + dx[i];

			if (nz < 1 || ny < 1 || nx < 1 || nz > h || ny > n || nx > m)
				continue;
			if (discovered[nz][ny][nx] >= 1)
				continue;
			if (board[nz][ny][nx] == -1)
				continue;
			if (board[nz][ny][nx] == 1)
				continue;
			
			discovered[nz][ny][nx] = discovered[here.z][here.y][here.x] + 1;
			q.push({ nz, ny, nx });
		}
	}

	//for (int i = 1; i <= h; ++i)
	//{
	//	for (int j = 1; j <= n; ++j)
	//	{
	//		for (int k = 1; k <= m; ++k)
	//		{
	//			cout << discovered[i][j][k];
	//		}
	//		cout << endl;
	//	}
	//}

	bool flag = false;
	int res = 0;
	for (int i = 1; i <= h; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			for (int k = 1; k <= m; ++k)
			{
				if (discovered[i][j][k] == 0 && board[i][j][k] != -1)
				{
					flag = true;
					cout << -1 << '\n';
					return;
				}

				res = max(res, discovered[i][j][k]);
			}
		}
	}

	cout << res - 1;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	//freopen("input.txt", "rt", stdin);

	setting();
	solve();

	return 0;
}

νƒœκ·Έ:

μΉ΄ν…Œκ³ λ¦¬:

μ—…λ°μ΄νŠΈ: