[BOJ] C++ 7569 "토마토" 문제 풀이 _ nov

    반응형

    #INFO

    난이도 : GOLD5

    문제유형 : BFS

    출처 : 7569번: 토마토 (acmicpc.net)

     

    7569번: 토마토

    첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,

    www.acmicpc.net


    #SOLVE

    BOJ7576: 토마토 문제와 거의 같은 문제이다. 다른 점 이라면 단지 Z축 좌표가 하나 추가 되었다는 것 뿐이다.

    int board[103][103][103] : 토마토의 정보를 저장해 줄 3차원 배열이다.bool isVisited[103][103][103] : 방문 여부를 저장해 줄 3차원 배열이다.int dist[103][103][103] : 거리의 정보를 저장해 줄 배열이다. dist 배열을 이용해 최소 일수를 계산한다.int checked[103][103][103] : 토마토가 모두 익지 못하는 상황을 체크하기 위한 배열이다. int dx[6], dy[6], dz[6] : x, y, z 축으로 이동하는 것을 도와주는 좌표 배열이다.

    #define Z first
    #define X second.first
    #define Y second.second
    int board[103][103][103];
    bool isVisited[103][103][103];
    int dist[103][103][103];
    int checked[103][103][103];
    int dx[6] = {0, 0, 1, 0, 0, -1};
    int dy[6] = {0, -1, 0, 0, 1, 0};
    int dz[6] = {1, 0, 0, -1, 0, 0};

     

    BFS 알고리즘을 위해 큐를 하나 선언했는데, 평면이 아닌 3차원이기에,  페어에 페어를 중첩시키는 방향으로 문제를 풀이했다. 혹은 STL의 튜플(tuple)을 이용해도 된다. 

    	int m, n, h;
    	cin >> m >> n >> h;
    	queue<pair<int, pair<int, int>>> Q;

     

    for 3중첩을 이용해 배열에 정보를 입력받는다.

    	for(int k = 0; k < h; k++){
    		for(int i = 0; i < n; i++){
    			for(int j = 0; j < m; j++){
    				cin >> board[k][i][j];
    				if(board[k][i][j] == 1) {
    					isVisited[k][i][j] = 1;
    					Q.push({k, {i, j}});
    				}
    				if(board[k][i][j] == 0) {
    					checked[k][i][j] = -1;
    				}
    			}
    		}
    	}

     

    BFS알고리즘을 수행한다.

    	while(!Q.empty()){
    		auto cur = Q.front();
    		Q.pop();
    		for(int dir = 0; dir < 6; dir++){
    			int nx = cur.X + dx[dir];
    			int ny = cur.Y + dy[dir];
    			int nz = cur.Z + dz[dir];
    			if(nx < 0 || nx >= n || ny < 0 || ny >= m || nz < 0 || nz >= h) continue;
    			if(isVisited[nz][nx][ny] || board[nz][nx][ny] != 0) continue;
    			dist[nz][nx][ny] = dist[cur.Z][cur.X][cur.Y] + 1;
    			isVisited[nz][nx][ny] = 1;
    			checked[nz][nx][ny] = 0;
    			Q.push({nz, {nx, ny}});
    		}
    	}

     

    마지막으로 day 변수에 거리값을 저장한 후 출력하면 된다.

    	int day = 0;
    	for(int k = 0; k < h; k++){
    		for(int i = 0; i < n; i++){
    			for(int j = 0; j < m; j++){
    				if(checked[k][i][j] == -1) {
    					cout << -1 << '\n';
    					return 0;
    				}		
    				day = max(day, dist[k][i][j]);
    			}
    		}
    	}
    
    	cout << day << '\n';

    #CODE

    #include <bits/stdc++.h>
    using namespace std;
    #define Z first
    #define X second.first
    #define Y second.second
    int board[103][103][103];
    bool isVisited[103][103][103];
    int dist[103][103][103];
    int checked[103][103][103];
    int dx[6] = {0, 0, 1, 0, 0, -1};
    int dy[6] = {0, -1, 0, 0, 1, 0};
    int dz[6] = {1, 0, 0, -1, 0, 0};
    
    int main(int argc, char* argv[]) {
    	ios::sync_with_stdio(0);
    	cin.tie(0);
    	int m, n, h;
    	cin >> m >> n >> h;
    	queue<pair<int, pair<int, int>>> Q;
    	for(int k = 0; k < h; k++){
    		for(int i = 0; i < n; i++){
    			for(int j = 0; j < m; j++){
    				cin >> board[k][i][j];
    				if(board[k][i][j] == 1) {
    					isVisited[k][i][j] = 1;
    					Q.push({k, {i, j}});
    				}
    				if(board[k][i][j] == 0) {
    					checked[k][i][j] = -1;
    				}
    			}
    		}
    	}
    
    	while(!Q.empty()){
    		auto cur = Q.front();
    		Q.pop();
    		for(int dir = 0; dir < 6; dir++){
    			int nx = cur.X + dx[dir];
    			int ny = cur.Y + dy[dir];
    			int nz = cur.Z + dz[dir];
    			if(nx < 0 || nx >= n || ny < 0 || ny >= m || nz < 0 || nz >= h) continue;
    			if(isVisited[nz][nx][ny] || board[nz][nx][ny] != 0) continue;
    			dist[nz][nx][ny] = dist[cur.Z][cur.X][cur.Y] + 1;
    			isVisited[nz][nx][ny] = 1;
    			checked[nz][nx][ny] = 0;
    			Q.push({nz, {nx, ny}});
    		}
    	}
    	
    	int day = 0;
    	for(int k = 0; k < h; k++){
    		for(int i = 0; i < n; i++){
    			for(int j = 0; j < m; j++){
    				if(checked[k][i][j] == -1) {
    					cout << -1 << '\n';
    					return 0;
    				}		
    				day = max(day, dist[k][i][j]);
    			}
    		}
    	}
    
    	cout << day << '\n';
    }
    반응형

    댓글

    Designed by JB FACTORY