[白俊C+]7569トマト
質問する
チョルスのトマト農場にはトマトを保管する大きな倉庫がある.トマトは下図のように一個ずつ四角い箱の格子に入れ、箱を垂直に積み上げて倉庫に保管します.
倉庫に保管されているトマトの中には、熟しているものもあれば、まだ熟していないものもあります.1日保管した後、熟したトマトに隣接する未熟のトマトは、熟したトマトの影響を受けて成熟する.1つのトマトに隣接する場所は、上、下、左、右、前、後の6方向に位置するトマトを意味する.対角線方向に影響を与えないトマトは、トマトが自分で成熟しないと仮定します.哲洙は倉庫に保管されているトマトが数日で熟成できるかどうか、少なくとも日数を知りたいと思っている.
倉庫にトマトのチェックボックスの大きさ、熟したトマトと未熟なトマトの情報を保管している場合、数日後には、トマトが熟しているかどうか、最低日数を求めるプログラムを作成します.しかし、箱のいくつかの格にはトマトが入っていないかもしれません.
入力
1行目は、ブロックサイズを表す2つの整数M、N、およびスタックされたブロック数を表すHを与える.Mは箱の横格子数,Nは箱の縦格子数を表す.しかし,2≦M≦100,2≦N≦100,1≦H≦100であった.2行目から、一番下の箱から一番上の箱まで、中に貯まっているトマトの情報があります.つまり、2行目からN行目まで、箱の中のトマトの情報が与えられます.各行の箱の横線のトマトの状態はM個の整数です.整数1は熟したトマトを表し、整数0は未熟のトマトを表し、整数-1はトマトを含まない格子を表す.このようなN線はH回繰り返し与えられる.
トマトが1つ以上ある場合にのみ入力します.
しゅつりょく
トマトを計算するには少なくとも数日かかります.保存からすべてのトマトが熟成している場合は0を、トマトが熟成していない場合は-1を出力します.
https://www.acmicpc.net/problem/7569
に答える
https://www.acmicpc.net/problem/7576題で箱をZ軸(高さH)に積み上げる問題です.
https://velog.io/@cldhfleks2/7576<<質問への回答
7576問との違いは,入力を受けるときに3次元配列として入力することである.
3つの軸の座標を表します.
ドットの構造体を発表した.
また、Z軸をブラウズするために
方向ベクトルを6個に増やします.
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using std::vector; using std::pair; using std::queue;
/*
안익은 토마토 : 1
익은 토마토는 : -1
ripeTomato : 1회용, 익은토마토 좌표
unripeTomato : 1회용, 안익은 토마토 좌표
*/
int n, m, h, ***tomato, unripeTomatoCnt, ***tomatoDays;
int dx[6] = {0, 0, 0, 1, 0, -1 };
int dy[6] = {0, 0, 1, 0, -1, 0 };
int dz[6] = { 1, -1, 0, 0, 0, 0 };
struct Point {
int x; int y; int z;
};
vector<Point> ripeTomato, unripeTomato;
queue <pair<Point, int>> loc;
void init();
void becomeRipe();
//익은 토마토를 기준으로 모든 안익은토마토를 익힌다.
//BFS사용하되, 모든 익은 토마토 좌표부터 days를 +1 씩 늘려가며 탐색하는데,
//안익은 토마토를 만날때마다 최솟값을 갱신해야함.
//즉 안익은토마토, 하나의 좌표를 여러번 방문해야하므로,
//방문 check를 하지않고 중복방문함
void becomeRipe() {
//처음에 모든 익은토마토좌표를 시작점으로 전부 넣음
for (int k = 0; k < ripeTomato.size(); k++) {
int start_x = ripeTomato[k].x;
int start_y = ripeTomato[k].y;
int start_z = ripeTomato[k].z;
loc.push({ Point{start_x, start_y, start_z}, 1 });
}
while (!loc.empty()) {
int x = loc.front().first.x; //현재위치 (x, y)
int y = loc.front().first.y;
int z = loc.front().first.z;
int days = loc.front().second;
loc.pop();
for (int dir = 0; dir < 6; dir++) { //다음 4방향(우,하,좌,상)
int xx = x + dx[dir]; //다음위치 (xx, yy)
int yy = y + dy[dir];
int zz = z + dz[dir];
//비정상 범위면 제외
if (xx < 0 || yy < 0 || zz < 0 ||
xx == n || yy == m || zz == h) continue;
//익은토마토나 빈공간을 만나면 제외
if (tomato[xx][yy][zz] == -1 || tomato[xx][yy][zz] == 0) continue;
//해당위치의 토마토가 가지는 일수는 항상 최솟값이어야함
if (tomatoDays[xx][yy][zz] > days) {
tomatoDays[xx][yy][zz] = days;
loc.push({ {xx, yy, zz}, days + 1 }); //최솟값을때 탐색을 이어나감
}
}
}
int res = 0; //최종 일수
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
for (int k = 0; k < h; k++) {
if (tomatoDays[i][j][k] == 0x7fffffff) {
//안익은 토마토의 일수가 초깃값(0x7fffffff)이면 고립된것이므로
//문제의 조건에의해 -1 출력
if (tomato[i][j][k] == 1) {
printf("-1");
return;
}
}
else {
if (res < tomatoDays[i][j][k]) //최솟값을 찾아감
res = tomatoDays[i][j][k];
}
}
printf("%d", res);
}
void init() {
scanf("%d%d%d", &m, &n, &h);
tomato = new int**[n];
tomatoDays = new int**[n];
for (int i = 0; i < n; i++) {
tomato[i] = new int* [m];
tomatoDays[i] = new int* [m];
for (int j = 0; j < m; j++) {
tomato[i][j] = new int[h];
tomatoDays[i][j] = new int[h];
}
}
for (int k = 0; k < h; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0, _; j < m; j++) {
scanf("%d", &_);
if (_ == 1) {
tomato[i][j][k] = -1; //익은것
ripeTomato.push_back(Point{ i, j, k });
}
else if (_ == 0) {
tomato[i][j][k] = 1; //안익은것
unripeTomato.push_back(Point{ i, j, k });
unripeTomatoCnt++; //안익은토마토갯수셈
}
else if (_ == -1)
tomato[i][j][k] = 0; //빈공간
tomatoDays[i][j][k] = 0x7fffffff; //최댓값으로 초기화
}
}
}
}
int main(void) {
init();
becomeRipe();
return 0;
}
Reference
この問題について([白俊C+]7569トマト), 我々は、より多くの情報をここで見つけました https://velog.io/@cldhfleks2/7569テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol