티스토리 뷰
1. 문제
https://www.acmicpc.net/problem/7569
7569번: 토마토
첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,
www.acmicpc.net
2. 문제 풀이
#include <iostream>
#include <bits/stdc++.h>
#pragma warning (disable:4996)
#define X first
#define Y second
using namespace std;
int board[105][105][105];
int dist[105][105][105];
int nx[6] = { 0,0,1,0,-1,0 };
int ny[6] = { 0,0,0,1,0,-1 };
int nz[6] = { 1,-1,0,0,0,0 };
int M, N, H;
int ans;
int main(void) {
iostream::sync_with_stdio(0);
cin.tie(0);
cin >> M >> N >> H;
queue<tuple<int,int,int>> Q;
for (int i = 0; i < H; i++)
for (int j = 0; j < N; j++)
fill(dist[i][j], dist[i][j] + M, -1);
for (int i = 0; i < H; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < M; k++) {
cin >> board[i][j][k];
if (board[i][j][k] == 1) {
Q.push({ i,j,k });
dist[i][j][k] = 0;
}
}
}
}
while (!Q.empty()) { // 0 1 2
auto cur = Q.front(); Q.pop();
for (int dir = 0; dir < 6; dir++) {
int dx = get<1>(cur) + nx[dir];
int dy = get<2>(cur) + ny[dir];
int dz = get<0>(cur) + nz[dir];
if (dx < 0 || dx >= N || dy < 0 || dy >= M || dz < 0 || dz >= H) continue;
if (board[dz][dx][dy] == -1 || dist[dz][dx][dy] >= 0) continue;
Q.push({ dz,dx,dy });
dist[dz][dx][dy] = dist[get<0>(cur)][get<1>(cur)][get<2>(cur)] + 1;
}
}
for (int i = 0; i < H; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < M; k++) {
if (board[i][j][k] == 0 && dist[i][j][k] == -1) {
cout << -1;
return 0;
}
ans = max(ans, dist[i][j][k]);
}
}
}
cout << ans;
}
3. 문제 평가 및 해설
이전에 올렸던 백준 7576 문제의 3차원 버전이다. 다음 링크는 2차원 토마토 문제이다.
https://devhater.tistory.com/25
[백준 7576/C++] 토마토
1. 문제 https://www.acmicpc.net/problem/7576 7576번: 토마토 첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000
devhater.tistory.com
처음 코드를 짜고 분명히 TC도 다 통과하고, 백준 질문 시판의 반례도 옳게 나왔는데 2%에서 "틀렸습니다!"가 계속 나왔다. 결국, 코드를 지우고 처음부터 다시 짰다.. 아직까지 원인을 모르겠다. 문제 풀이는 2차원 토마토에서 3차원으로 차원을 확장한 것과 같다. 간단히 설명하자면 다음과 같다.
1. 3차원은 상하좌우 + 위아래 까지 생각해야 하므로, 이동할 수 있는 경우가 6가지이다. 따라서 nx,ny,nz 배열도 6개로 설정해주어야 한다.
2. 이동할 수 있는 통로가 6가지로 늘었으니, 예외처리도 늘려야 한다. 높이에 대한 두 가지 예외처리(음수이거나, H를 넘어섰을 때)를 해주면 된다.
3. 익지 않은 토마토가 존재한다면, 종료하고 -1를 출력해야한다.
실수할 수 있는 부분은 M,N을 착각하거나, 예외처리를 해주지 않은 경우가 있겠다. 혹시라도 독자분들 중에 내 틀린 소스코드 중 문제점(?)을 찾고 싶다면 다음 링크를 참고하면 된다.. 아직까지 맞왜틀을 외치는 중 이지만, 다시 짠 코드가 훨씬 깔끔해서 잊고 넘어갈 생각이다.
https://www.acmicpc.net/source/64657162
로그인
www.acmicpc.net
'백준(C++) > 문제풀이' 카테고리의 다른 글
[백준1074/C++] Z (0) | 2023.08.17 |
---|---|
[백준 1697/C++] 숨바꼭질 (0) | 2023.08.05 |
[백준 4179/C++] 불! (0) | 2023.08.04 |
[백준 7576/C++] 토마토 (0) | 2023.07.29 |
[백준 2178/C++] 미로 탐색 (0) | 2023.07.28 |
- Total
- Today
- Yesterday
- #include<bits/stdc++.h> # Visual studio #코딩테스트 꿀팁 #알고리즘 풀이
- 백준 5430
- 알고리즘 풀이
- 백준 1697
- constraint missing 오류
- 백준1158
- C++
- 백준 7569
- 코딩테스트
- 백준 2178
- Render Problem
- 백준 1021
- 백준 2164
- AAR metadata 에러
- 백준 4949
- 코테
- 안드로이드 스튜디오
- 백준 7576
- 알고리즘
- android studio
- 백준 3986
- 문제 유형
- 백준 #알고리즘 풀이 #백준 1475
- ViewBinding
- 백준 4179
- 알고리즘 정리
- 알고리즘 #백준 3273 #C++
- 백준 2493
- C++ #알고리즘 #코딩테스트
- C++ #알고리즘 #연결리스트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |