https://www.acmicpc.net/problem/18809
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
public static int N, M, G, R, ans = 0, cnt = 0;
public static int[] green, red, visited;
public static int[][] map, copyMap;
public static int[] dr = { -1, 0, 1, 0 };
public static int[] dc = { 0, 1, 0, -1 };
public static List<int[]> list = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
// 1. 입력받기
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
G = Integer.parseInt(st.nextToken());
R = Integer.parseInt(st.nextToken());
map = new int[N][M];
copyMap = new int[N][M];
green = new int[G]; // 초록색 배양액 위치
red = new int[R]; // 빨간색 배양액 위치
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
// 배양액을 뿌릴 수 있는 땅 리스트에 저장
if (map[i][j] == 2) {
list.add(new int[] { i, j });
cnt++;
}
}
}
visited = new int[cnt];
// 2. 배양액 위치 설정
// 2-1. 초록색 배양액 위치
cGreen(0, 0);
// 4. 출력하기
System.out.println(ans);
}
public static void cGreen(int at, int depth) {
if (depth == G) {
// 2-1. 빨간색 배양액 위치
cRed(0, 0);
return;
}
for (int i = at; i < cnt; i++) {
green[depth] = i;
visited[i] = 1;
cGreen(i + 1, depth + 1);
visited[i] = 0;
}
}
public static void cRed(int at, int depth) {
if (depth == R) {
// 3. 퍼트리기
copy();
pu();
int tmp = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (copyMap[i][j] == 3) {
tmp++;
}
}
}
if (tmp > ans) {
ans = tmp;
}
return;
}
for (int i = at; i < cnt; i++) {
if (visited[i] == 0) {
red[depth] = i;
cRed(i + 1, depth + 1);
}
}
}
public static void pu() {
// 3-1. 초록색, 빨간색 배양액 뿌리기
Queue<int[]> gQ = new LinkedList<>();
Queue<int[]> rQ = new LinkedList<>();
int time = 0;
for (int i = 0; i < G; i++) { // 초록색
int idx = green[i];
int[] cur = list.get(idx);
gQ.offer(new int[] { cur[0], cur[1] });
copyMap[cur[0]][cur[1]] = 0;
}
for (int i = 0; i < R; i++) { // 빨간색
int idx = red[i];
int[] cur = list.get(idx);
rQ.offer(new int[] { cur[0], cur[1] });
copyMap[cur[0]][cur[1]] = 0;
}
// 3-2. 1초에 한번씩 뿌리기
while (!gQ.isEmpty() || !rQ.isEmpty()) {
int gSize = gQ.size();
int rSize = rQ.size();
time++;
for (int i = 0; i < gSize; i++) { // 초록색 퍼지기
int[] cur = gQ.poll();
if(copyMap[cur[0]][cur[1]] == 3) {
continue;
}
for (int d = 0; d < 4; d++) {
int nr = cur[0] + dr[d];
int nc = cur[1] + dc[d];
if (nr < 0 || nr >= N || nc < 0 || nc >= M)
continue;
int cv = copyMap[nr][nc];
if (cv == 1 || cv == 2) {
copyMap[nr][nc] = 4 * time;
gQ.offer(new int[] { nr, nc });
}
}
}
for (int i = 0; i < rSize; i++) { // 빨간색 퍼지기
int[] cur = rQ.poll();
for (int d = 0; d < 4; d++) {
int nr = cur[0] + dr[d];
int nc = cur[1] + dc[d];
if (nr < 0 || nr >= N || nc < 0 || nc >= M)
continue;
int cv = copyMap[nr][nc];
if (cv == 4 * time) {
copyMap[nr][nc] = 3;
continue;
}
if (cv == 1 || cv == 2) {
copyMap[nr][nc] = 0;
rQ.offer(new int[] { nr, nc });
}
}
}
}
}
public static void copy() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
copyMap[i][j] = map[i][j];
}
}
}
}
'코딩테스트 > JAVA' 카테고리의 다른 글
[백준 JAVA] 1012번: 유기농 배추 (0) | 2025.01.06 |
---|---|
[SWEA] 1824번: 혁진이의 프로그램 검증 (1) | 2024.11.15 |
[프로그래머스 JAVA] 지형 이동 (0) | 2024.10.30 |
[백준 JAVA] 18429번: 근손실 (0) | 2024.10.25 |
[백준 JAVA] 1074번: Z (0) | 2024.10.23 |