[BOJ16235] 나무재테크
리뷰
삼성 기출 문제라서 그런지 유형 자체가 딱 삼성 코테스러웠다.
풀고나서 다른 사람들 풀이보니깐 시간을 훨씬 줄일 수 있는 방법들이 많이 있었다.
아직까지 문제풀면서 그런 방법들을 쓰면서 푸는 능력이 많이 부족한 듯.
최적화까지는 고려하지않아도 되는 문제여서 단순 구현으로만 해결해서 코드가 많이 지저분하다.
시간재고 풀었는데 시간안에는 해결 완료.
다음에 꼭 이쁘고 단순한 코드로 다시 풀어서 올려야지.
코드리뷰
구현에 있어서 역시나 미리 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;
}
댓글남기기