BOJ 5212 지구온난화
-
변수
int R, C // 지도의 행, 열 char[][] map // 남해의 지도 map char[][] ansMap // 삼다도이면 X를 .로 바꿔주는 정답 맵을 출력하기 위한 변수 + rs // 정답 map을 뽑기 위해 0부터 R까지 순회하며 'X'가 처음 나오는 row, min row값 cs // 첫 col 값 re // R-1행부터 --로 순회해서 X좌표가 나오는 max row값 ce // max col 값
-
구현로직
-
4방 탐색을 해서 . 의 개수를 count
-
count==3이면 X를 .로 변경
-
1행부터 X가 나올때까지 1행 쭉 탐색하고 X가 없는 행이면 행 삭제
같은 방법으로 1행부터 열 탐색하고 X가 없는 열이면 열 삭제
반대로 마지막행, 마지막 열부터도 위와 같은 방식으로 체크 후 행, 열 삭제
=> 행과 열을 삭제하는 법을 몰라서 4번 방법으로 변경
-
전략 ) X가 시작하는 최소 지점부터 X가 끝나는 최대지점 값을 활용해
해당 부분만 출력
=> 행의 시작부터 순회(++)하면서 X가 있으면 해당 행의 정보 rs, cs변수에 저장하고 return
행의 끝(R-1)부터 순회(–)하면서 X가 있으면 해당 행의 정보 re, ce변수에 저장하고 return
-
-
코드
package baekjoon.Silver; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.Queue; import java.util.StringTokenizer; public class BOJ_5212_지구온난화 { private static char[][] map; private static char[][] ansMap; private static Queue<Island> q; private static int R; private static int C; private static int rs, cs, re, ce; private static class Island { int r, c; public Island(int r, int c) { super(); this.r = r; this.c = c; } } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); R = Integer.parseInt(st.nextToken()); C = Integer.parseInt(st.nextToken()); q = new LinkedList<Island>(); map = new char[R][C]; ansMap = new char[R][C]; // 주어진 map 입력받기 for (int i = 0; i < R; i++) { String str = br.readLine(); for (int j = 0; j < C; j++) { map[i][j] = str.charAt(j); ansMap[i][j] = str.charAt(j); } } // (*) 이 부분 한 번 더 반복 돌리지 말고 위에 map[i][j]받은 뒤에 넣어주기 // 그럼 시간이 좀 더 줄을 것 같음 for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { if (map[i][j] == 'X') q.add(new Island(i, j)); } } bfs(); // printAnsMap(); checkRStart(0); checkCStart(0); checkREnd(R - 1); checkCEnd(C - 1); for (int i = rs; i <= re; i++) { for (int j = cs; j <= ce; j++) { System.out.print(ansMap[i][j]); } System.out.println(); } } private static void checkCStart(int start) { for (int j = start; j < C; j++) { // 열 탐색 for (int i = 0; i < R; i++) { if (ansMap[i][j] == 'X') { cs = j; return; } } } } private static void checkRStart(int start) { for (int i = start; i < R; i++) { // 행 탐색 for (int j = 0; j < C; j++) { if (ansMap[i][j] == 'X') { rs = i; // System.out.println("rs : " + rs); return; } } } } private static void checkCEnd(int end) { for (int j = end; j >= 0; j--) { // 열 탐색 for (int i = 0; i < R; i++) { if (ansMap[i][j] == 'X') { ce = j; return; } } } } private static void checkREnd(int end) { for (int i = end; i >= 0; i--) { // 행 탐색 for (int j = 0; j < C; j++) { if (ansMap[i][j] == 'X') { re = i; return; } } } } private static void printAnsMap() { for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { System.out.print(ansMap[i][j]); } System.out.println(); } } static int[] dr = { -1, 1, 0, 0 }; // 상 하 좌 우 static int[] dc = { 0, 0, -1, 1 }; private static void bfs() { while (!q.isEmpty()) { Island i = q.poll(); int count = 0; // 바다의 개수 체크 for (int k = 0; k < 4; k++) { int nr = i.r + dr[k]; int nc = i.c + dc[k]; if (nr < 0 || nc < 0 || nr >= R || nc >= C || map[nr][nc] == '.') { count += 1; } if (count == 3) { // (*) 이 부분도 for문 안에 돌려서 계속 조건을 비교하기 보다 for문 밖에서 count>=3이상인 경우로 한번 체크하면 시간 효율이 UP! ansMap[i.r][i.c] = '.'; } } } } }
-
느낀점
-
반복코드가 많아서 코드 줄 수가 길어졌다. 코드 줄 수를 줄이면서 다른 방법으로 어떻게 효율적으로 풀 수 있을지 확인하기
-
오류가 났던 부분(*)은 if문을 열고 한줄은 자동 적용되서 if( ) { 여기 부분 } 이렇게 중괄호 치는 것을 잘 처리 안해주니까 return 부분이 if문안으로 들어가지 않아서 에러났었다
-> if( )로 조건문 열면 한 줄이어도 무조건 중괄호 처리 해주기!
-
-
코드 리뷰한 내용은 (*)로 주석 처리했음!
Leave a comment