[BOJ16235] 나무재테크

3 분 소요

리뷰

삼성 기출 문제라서 그런지 유형 자체가 딱 삼성 코테스러웠다.

풀고나서 다른 사람들 풀이보니깐 시간을 훨씬 줄일 수 있는 방법들이 많이 있었다.

아직까지 문제풀면서 그런 방법들을 쓰면서 푸는 능력이 많이 부족한 듯.

최적화까지는 고려하지않아도 되는 문제여서 단순 구현으로만 해결해서 코드가 많이 지저분하다.

시간재고 풀었는데 시간안에는 해결 완료.

다음에 꼭 이쁘고 단순한 코드로 다시 풀어서 올려야지.

코드리뷰

구현에 있어서 역시나 미리 30분~1시간정도 정리해놓고 들어가는게 실수를 줄이는 방법.

창피하지만 3차원 배열을 이용해서 풀었는데 board[x][y][z]로 x,y는 나무의 좌표 , z는 나무의 나이로 인덱스를 잡고 배열 값으로는 개수를 넣었다.

풀고 친구랑 리뷰하면서 느낀건데 가장 중요한 부분이 봄에서 죽어서 양분이 되거나, 양분먹고 나이가 증가하는 곳에서 바로 값을 증가시키거나 추가하면 안되고, 봄 활동이 끝나고 나서추가하는게 key point라 생각했다. 왜냐하면 거기서 바로 증가시키면, 봄 반복문을 돌면서 증가된 부분을 다시 또 고려하게 되서 결과값이 틀리게 나온다.

저 부분말고는 딱히 어려운 부분은 없었던 문제.

/*BOJ16235 나무 제테크*/

#include <iostream>
using namespace std;

int N, M, K; //N은 땅 길이 ,M은 나무 갯수 , K는 몇년 지났는지
int x, y, z; //나무 위치 (x,y) 나무 나이 z
int A[15][15];
int board[15][15][1020]; //땅에 나이별로 나무 갯수 저장
int store_board[15][15][1020]; //봄과 여름에 작업되는 나무와 양분을 저장해놓는 배열

void pre_foods() {
	for (int i = 1; i <= N; i++) { //초기 땅에는 양분이 5로 들어있다.(0 에 저장)
		for (int j = 1; j <= N; j++) {
			board[i][j][0] = 5;
		}
	}
}
void spring() { //for spring
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			for (int k = 1; k < 1020; k++) {
				if (board[i][j][k] != 0) {
					while (board[i][j][k] > 0) {
						if (k <= board[i][j][0]) { // 나무의 나이가 양분보다 작은 경우
							board[i][j][0] -= k;
							store_board[i][j][k + 1]++; //여기서 바로 board를 올리면, 반복문 돌면서 또 보게되서
							board[i][j][k]--;
						}
						else { //큰 경우
							store_board[i][j][0] += (board[i][j][k] * (k / 2)); //위에와 같은 이유
							board[i][j][k] = 0;
						}
					}
				}
			}
		}
	}
}
void summer() { //for summer
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			for (int k = 0; k < 1020; k++) {
				board[i][j][k] += store_board[i][j][k];
				store_board[i][j][k] = 0;
			}
		}
	}
}
void fall() { //for fall
	int dr[8] = { -1, -1, -1, 0, 0, 1, 1, 1 };
	int dc[8] = { -1, 0, 1, -1, 1, -1, 0, 1 };
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			int k = 5;
			while (k<1020) {
				if (board[i][j][k] != 0) {
					for (int n = 0; n < 8; n++) {
						int nnext = i + dr[n];
						int mnext = j + dc[n];
						if (nnext >= 1 && nnext <= N && mnext >= 1 && mnext <= N) {
							board[nnext][mnext][1] += board[i][j][k];
						}
					}
				}
				k += 5;
			}
		}
	}
}

void winter() {
	for (int i = 1; i <= N; i++) { //for winter
		for (int j = 1; j <= N; j++) {
			board[i][j][0] += A[i][j];
		}
	}
}

int count_up() {
	int cnt = 0;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			for (int k = 1; k < 1020; k++) {
				if (board[i][j][k] != 0) {
					cnt += board[i][j][k];
				}
			}
		}
	}
	return cnt;
}

int main() {
	scanf("%d%d%d", &N, &M, &K);
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			scanf("%d", &A[i][j]);
		}
	}
	for (int i = 1; i <= M; i++) {
		scanf("%d%d%d", &x, &y, &z);
		board[x][y][z]++; //나이가 z인 나무를 좌표에 따라 카운트 업
	}
	pre_foods();
	while (K > 0) {
		spring();
		summer();
		fall();
		winter();
		K--;
	}
	printf("%d", count_up());
	return 0;
}

댓글남기기