https://www.acmicpc.net/problem/17232
문제
- 첫째 줄에 바둑판의 세로 길이 N, 가로 길이 M, 관찰하는 시간 T ( 1 <= N, M <= 100, 1 <= T <= 300 ) 이 입력된다.
- 둘째 줄에 주위의 기준이 되는 정수 K, 각 칸의 다음 상황을 결정하는 정수 a, b ( 0 <= a, b <= ( 2 * K + 1 ) ^ 2 ) 이 입력된다.
- 셋째 줄부터 N개의 줄에 걸쳐 각 줄에 M개씩 바둑판의 처음 상태가 주어진다. 생명이 있는 칸은 ' * ', 빈칸은 ' . ' 로 입력된다.
- K를 이용하는 주위라는 것은 현재 칸을 중심으로 둔 한 변의 길이가 ( 2 * K + 1 ) 인 정사각형에서 현재 칸을 제외한 영역을 말한다.
- 주위에 몇 개의 생명이 존재하는지에 따라 다음 명령을 수행하며, 생명은 바둑판을 벗어난 영역에서 생존할 수 없다.
- 생존 : 만약 현재 칸에 생명이 있고, 주위에 a개 이상 b개 이하의 생명이 있다면 현재 칸의 생명은 다음 단계에 살아남는다.
- 고독 : 만약 현재 칸에 생명이 있고, 주위에 a개 미만의 생명이 있다면 현재 칸의 생명은 외로워서 죽는다.
- 과밀 : 만약 현재 칸에 생명이 있고, 주위에 b개 초과의 생명이 있다면 현재 칸의 생명은 과밀로 죽는다.
- 탄생 : 만약 현재 칸에 생명이 없고, 주위에 a개 초과 b개 이하의 생명이 있다면 다음 단계에서 현재 칸에 생명이 생긴다.
- T시간 뒤의 생명을 관찰하여 출력한다.
정답 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int T = Integer.parseInt(st.nextToken());
String[][] board = new String[N + 1][M + 1];
st = new StringTokenizer(br.readLine());
int K = Integer.parseInt(st.nextToken());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
for (int i = 1; i <= N; i++) {
String[] temp = br.readLine().split("");
for (int j = 1; j <= M; j++) {
board[i][j] = temp[j - 1];
}
}
for (int i = 0; i < T; i++) {
int[][] sum = new int[N + 1][M + 1]; // 배열의 깊은 복사
for (int y = 1; y <= N; y++) { // 복사한 배열의 구간합
for (int x = 1; x <= M; x++) {
sum[y][x] = sum[y - 1][x] + sum[y][x - 1] - sum[y - 1][x - 1] + (Objects.equals(board[y][x], "*") ? 1 : 0);
}
}
for (int y = 1; y <= N; y++) { // 현 단계의 결과
for (int x = 1; x <= M; x++) {
int r1 = Math.max(y - K, 1);
int c1 = Math.max(x - K, 1);
int r2 = Math.min(y + K, N);
int c2 = Math.min(x + K, M);
int num = sum[r2][c2] - sum[r1 - 1][c2] - sum[r2][c1 - 1] + sum[r1 - 1][c1 - 1];
if (Objects.equals(board[y][x], "*")) {
num--; // 현재 칸의 수를 뺌
if (num < a || b < num) { // 고독, 과밀
board[y][x] = ".";
}
} else if (a < num && num <= b) { //탄생
board[y][x] = "*";
}
}
}
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
}
}
어떻게 풀어야 될지 감은 금방 잡히나 금방 풀기는 힘들었다.
어떻게 합을 구하여 어떻게 값을 구해야 될지를 정하는 것이 관건인 문제인 듯 하다.
주위에 있는 생명의 수와 그 생명의 수를 구할 때 사용할 배열을 만드는 두 가지만 잘 만든다면 풀리는 문제인 것 같으나
나는 어려워서 혼자 풀지는 못했다.
배열까진 구했는데 주위에 있는 생명의 수를 어떻게 구해야 될 지 모르겠어서 도움을 조금 구했다.
'백준 문제 풀이 > 백준 (JAVA)' 카테고리의 다른 글
JAVA 백준 1654 랜선 자르기 (이분 탐색) (0) | 2025.05.24 |
---|---|
JAVA 백준 2805 나무 자르기 (이분 탐색) (0) | 2025.05.23 |
JAVA 백준 19951 태상이의 훈련소 생활 (누적합) (0) | 2025.05.21 |
JAVA 백준 16713 Generic Queries (누적합) (0) | 2025.05.20 |
JAVA 백준 1931 회의실 배정 (정렬) (0) | 2025.05.20 |