< 문제 >
https://www.acmicpc.net/problem/5212
package silver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class P5212 {
// 지구 온난화
static char origin[][]; //원본 배열
static char changed[][];//바뀐 배열
static int R, C;
//상하좌우가 바다인지 확인하고 3면 이상이 바다이면 바다로 바꾸는 함수
static void check(int x, int y) {
int cnt = 0;
if (x < 1)
cnt++;
else {
if (origin[x - 1][y] == '.') // 상
cnt++;
}
if (x > R - 2)
cnt++;
else {
if (origin[x + 1][y] == '.') // 하
cnt++;
}
if (y <= 0)
cnt++;
else {
if (origin[x][y - 1] == '.') // 좌
cnt++;
}
if (y > C - 2)
cnt++;
else {
if (origin[x][y + 1] == '.') // 우
cnt++;
}
if (cnt >= 3) // 만약 바다가 3개 이상이면
changed[x][y] = '.'; // 바다로 바꿈
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken()); // 세로
C = Integer.parseInt(st.nextToken()); // 가로
origin = new char[R][C];
changed = new char[R][C];
for (int i = 0; i < R; i++) {
String s = br.readLine();
for (int j = 0; j < C; j++) {
origin[i][j] = s.charAt(j); // 배열에 값을 저장
}
}
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
changed[i][j] = origin[i][j]; // 2차원 배열은 clone 함수로 깊은 복사 안됨
}
}
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (origin[i][j] == 'X') { // 땅일 경우
check(i, j); // 상하좌우 바다인지 확인
}
}
}
// 좁아진 땅 출력을 위해 행의 최솟값 최댓값, 열의 최솟값 최댓값 구하기
int rmin=10,rmax=0,cmin=10,cmax=0;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (changed[i][j] == 'X') {
rmin=Math.min(rmin, i);
rmax=Math.max(rmax, i);
cmin=Math.min(cmin, j);
cmax=Math.max(cmax, j);
}
}
}
//출력
for (int i = rmin; i <=rmax; i++) {
for (int j = cmin; j <= cmax; j++) {
System.out.print(changed[i][j]);
}
System.out.println();
}
}
}
✏️ 풀이 방법
1. 2차원 배열 origin 에 값을 입력받는다.
2. 배열 changed 에 origin 배열의 값을 똑같이 저장한다.
3. origin 배열의 값이 'X' 일 경우 ( 땅일 경우) => 상하좌우가 바다인지 확인한다.
: check 함수 실행 => 상 하 좌 우가 배열의 범위를 넘어갈 경우, 바다이므로 cnt 증가
=> 상 하 좌 우의 값이 '.' 일 경우 바다이므로 cnt 증가
=> cnt 의 값이 3 이상이면, 즉 3면 이상이 바다로 둘러싸여있으면 changed 배열의 해당 위치를 바다로 변경
4. 작아진 지도의 크기를 구하기 위해, 값이 'X' 일 경우의 행 열의 최솟값과 최댓값을 구한다.
5. 행의 최소~ 최대, 열의 최소~ 최대에 해당하는 땅을 출력한다.
✍🏻 느낀점
이런 유형의 문제를 너무 오랜만에 풀어봐서 입력받는것조차 까먹었다 ㅋㅋㅋㅋㅋ,, 당황한,, 그리고 check 함수에서 범위를 어떻게 설정해야할지 생각을 잘못해서 이 부분에서 뻘짓을 너무 많이 했다. 배열의 맨 마지막 인덱스는 [R-1][C-1]인데, 이것을 생각 못하고 R과 C로 계산해서 제대로 된 결과가 출력되지 않았다 ㅜㅜ 그리고,, 좁아진 땅을 계산하기 위해 최대 최소를 구해야 하는건 알겠는데 이것을 어떻게 할까 list에 넣어서 해야하나 고민하다가 너무 복잡해질 것 같아서 다른 블로그를 참고해서 문제를 풀었다. 엉엉.. 이 문제 나는 왜 이렇게까지 복잡하게 푼건지 모르겠다,, 여러 방면에서 내 부족한 점을 깨닫게 해준 문제였다.
참고 블로그
https://bacchus-lover.tistory.com/469
https://hanyeop.tistory.com/366 // 2차원 배열은 냅다 clone 하면 깊은 복사 안됨, 즉 동일한 주솟값을 가지게 됨
'코딩테스트 > Baekjoon' 카테고리의 다른 글
[JAVA] 백준 12873번: 기념품 (0) | 2024.05.15 |
---|---|
[JAVA] 백준 26215번: 눈 치우기 (0) | 2024.05.12 |
[JAVA] 백준 17952번: 과제는 끝나지 않아! (0) | 2024.04.09 |
[JAVA] 백준 2002번: 추월 (0) | 2024.03.25 |
[JAVA] 백준 1713번: 후보 추천하기 (0) | 2024.03.22 |