7569번: 토마토
첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,
www.acmicpc.net
- 7576 문제에서 '층' 이라는 개념이 추가된 것.
- '층' 이라는 개념만 추가해서 구현해주면된다.
- 위층, 아래층, 상, 하, 좌, 우를 고려해준다.
- std 라이브러리를 최대한 사용하지 않고, 배열을 1차원으로만 사용한다면 속도 향상이 된다.
- 코드
더보기
#include <iostream>
#include <vector>
#include <queue>
// struct
struct POS
{
POS()
{
h = x = y = 0;
}
POS(int _h, int _x, int _y)
{
h = _h;
x = _x;
y = _y;
}
int h;
int x;
int y;
};
// def
#define MAX_SIZE 100
#define PAIR std::pair<POS, int>
// global
// h, n, m
std::vector<int> board[MAX_SIZE + 1][MAX_SIZE + 1];
bool visited[MAX_SIZE + 1][MAX_SIZE + 1][MAX_SIZE + 1];
// 윗층, 아래층, 상 하 좌 우
int direction[6][3] = {
{-1, 0, 0}, {1, 0, 0},
{0, -1, 0}, {0, 1, 0},
{0, 0, -1}, {0, 0, 1}
};
// method
bool Checking(int h, int x, int y, int H, int X, int Y);
int BFS(int H, int X, int Y, int zeroCnt, std::vector<POS>& startList);
int main()
{
// 7569 - 토마토 3차원
std::ios::sync_with_stdio(false);
std::setbuf(stdout, NULL);
int N; // 세로
int M; // 가로
int H; // 층수
(void)scanf("%d %d %d", &M, &N, &H);
// input
std::vector<POS> startList;
int zeroCount = 0;
for (int h = 0; h < H; h++)
{
for (int n = 0; n < N; n++)
{
for (int m = 0; m < M; m++)
{
int input = 0;
(void)scanf("%d", &input);
if (1 == input)
{
POS temp(h, n, m);
startList.push_back(temp);
}
else if (0 == input)
zeroCount++;
board[h][n].push_back(input);
}
}
}
// bfs
const int answer = BFS(H, N, M, zeroCount, startList);
// print
printf("%d", answer);
return 0;
}
bool Checking(int h, int x, int y, int H, int X, int Y)
{
bool retValue = true;
if ((h < 0 || h >= H) || (x < 0 || x >= X) || (y < 0 || y >= Y))
retValue = false;
return retValue;
}
int BFS(int H, int X, int Y, int zeroCnt, std::vector<POS>& startList)
{
int retValue = 0;
if (0 == zeroCnt)
return retValue;
// init
std::queue<PAIR> que;
for (POS& data : startList)
{
que.push(PAIR(data, 0));
visited[data.h][data.x][data.y] = true;
}
int count = 0;
while (!que.empty())
{
PAIR pair = que.front();
que.pop();
POS pos = pair.first;
int day = pair.second;
retValue = day;
for (int d = 0; d < 6; d++)
{
int h = pos.h - direction[d][0];
int x = pos.x - direction[d][1];
int y = pos.y - direction[d][2];
const bool bIsValid = Checking(h, x, y, H, X, Y);
if (true == bIsValid)
{
if (false == visited[h][x][y] && -1 != board[h][x][y])
{
que.push(PAIR(POS(h, x, y), day + 1));
visited[h][x][y] = true;
if (0 == board[h][x][y])
{
board[h][x][y] = 1;
count++;
}
}
}
else
continue;
}
}
// answer
if (count != zeroCnt)
retValue = -1;
return retValue;
}
'Coding Problem > 백준' 카테고리의 다른 글
[백준] 2206 - 벽 부수고 이동하기 (0) | 2020.12.08 |
---|---|
[백준] 1697 - 숨박꼭질 (0) | 2020.12.07 |
[백준] 7576 - 토마토 (0) | 2020.12.04 |
[백준] 2178 - 미로 탐색 (0) | 2020.12.01 |
[백준] 1012 - 유기농 배추 (0) | 2020.12.01 |