삼성 2022 상반기 오후 기출2번 

0KB, 21ms

 

https://www.codetree.ai/frequent-problems/tree-kill-all/description

 

  • BFS + 구현
  • 주의점
    • 벽이 있거나 나무가 없어도 스프레이는 뿌려야한다.
#include <iostream>
#include <queue>
#include <iomanip>

#define MAX 20
using namespace std;

int map[MAX][MAX] = {}, spray[MAX][MAX] = {};
int N, M, K, C;

int dy[4] = { -1,1,0,0 }, dx[4] = { 0,0,-1,1 };
int dyy[4] = { -1,-1,1,1 }, dxx[4] = { -1,1,1,-1 };

int answer = 0;

typedef struct tree {
	int y, x;
	int k;
	int dir;
}TREE;

void input() {
	cin >> N >> M >> K >> C;
	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			cin >> map[i][j];
}

void grow() {
	for(int i=0; i<N; i++)
		for (int j = 0; j < N; j++) {
			if (spray[i][j] > 0) spray[i][j]--;
			if (map[i][j] <= 0) continue;
			int cnt = 0;
			for (int p = 0; p < 4; p++) {
				int y = i + dy[p], x = j + dx[p];
				if (y >= N || x >= N || y < 0 || x < 0) continue;

				if (map[y][x] > 0) cnt++;
			}
			map[i][j] += cnt;
		}
}

void spread() {
	int copy[MAX][MAX] = {};
	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			copy[i][j] = map[i][j];

	for(int i=0; i<N; i++)
		for (int j = 0; j < N; j++) {
			if (copy[i][j] <= 0) continue;
			
			int cnt = 0, y, x;
			for (int p = 0; p < 4; p++) { // 1600
				y = i + dy[p]; x = j + dx[p];
				if (y >= N || x >= N || y < 0 || x < 0 
					|| spray[y][x] > 0) continue;

				if (copy[y][x] == 0) cnt++;
			}

			for (int p = 0; p < 4; p++) {
				y = i + dy[p]; x = j + dx[p];
				if (y >= N || x >= N || y < 0 || x < 0 || spray[y][x] > 0) continue;

				if (copy[y][x] == 0) map[y][x] += copy[i][j] / cnt;
			}
		}
}

pair<int, int> get_spray() {
	pair<int,int> res;
	int res_num = -1;

	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (map[i][j] <= 0) continue;

			bool visited[MAX][MAX] = {};
			int num = 0; 
			queue<TREE> q;

			visited[i][j] = true;
			num += map[i][j];

			q.push({ i, j, 0, 0 });
			q.push({ i, j, 0, 1 });
			q.push({ i, j, 0, 2 });
			q.push({ i, j, 0, 3 });

			while (!q.empty()) {
				TREE now = q.front(); q.pop();
				if (now.k == K) continue;

				int new_y = now.y + dyy[now.dir], new_x = now.x + dxx[now.dir];
				if (new_y >= N || new_x >= N 
					|| new_y < 0 || new_x < 0 
					|| visited[new_y][new_x]
					|| map[new_y][new_x] <= 0) continue;

					visited[new_y][new_x] = true;
					num += map[new_y][new_x];
					q.push({new_y, new_x, now.k+1, now.dir});
			}

			if (res_num < num) {
				res_num = num;
				res = { i, j };
			}
		}
	}

	if (res_num == -1) res = { 0,0 };

	return res;
}

void set_spray(pair<int, int> ch) {
	int y = ch.first, x = ch.second;
	bool visited[MAX][MAX] = {};
	queue<TREE> q;

	if (map[y][x] <= 0) {
		spray[y][x] = C + 1;
		return;
	}

	visited[y][x] = true;
	q.push({ y, x, 0, 0 });
	q.push({ y, x, 0, 1 });
	q.push({ y, x, 0, 2 });
	q.push({ y, x, 0, 3 });
	answer += map[y][x];
	map[y][x] = 0;
	spray[y][x] = C + 1;
	
	while (!q.empty()) {
		TREE now = q.front(); q.pop();
		if (now.k == K) continue;

		int new_y = now.y + dyy[now.dir], new_x = now.x + dxx[now.dir];
		if (new_y >= N || new_x >= N
			|| new_y < 0 || new_x < 0
			|| visited[new_y][new_x]) continue;

		if (map[new_y][new_x] <= 0) {
			spray[new_y][new_x] = C + 1;
			continue;
		}

		visited[new_y][new_x] = true;
		answer += map[new_y][new_x];
		map[new_y][new_x] = 0;
		spray[new_y][new_x] = C + 1;
		q.push({ new_y, new_x, now.k + 1, now.dir });
	}
}

void solve() {
	while (M--) {
		grow();
		spread();
		
		pair<int, int> choice = get_spray();
		set_spray(choice);
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	input();
	solve();

	cout << answer;

	return 0;
}

'coding > baekjoon_codingstudy' 카테고리의 다른 글

20058 마법사 상어와 파이어스톰  (0) 2022.10.12
21608 상어 초등학교  (0) 2022.10.11
21610 마법사 상어와 비바라기  (0) 2022.10.11
20057 마법사 상어와 토네이도  (0) 2022.10.10
17825 주사위 윷놀이  (0) 2022.10.10

+ Recent posts