BOJ 5212 지구온난화

3 minute read

  1. 변수

    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 값
    
  2. 구현로직

    1. 4방 탐색을 해서 . 의 개수를 count

    2. count==3이면 X를 .로 변경

    3. 1행부터 X가 나올때까지 1행 쭉 탐색하고 X가 없는 행이면 행 삭제

      같은 방법으로 1행부터 열 탐색하고 X가 없는 열이면 열 삭제

      반대로 마지막행, 마지막 열부터도 위와 같은 방식으로 체크 후 행, 열 삭제

      => 행과 열을 삭제하는 법을 몰라서 4번 방법으로 변경

    4. 전략 ) X가 시작하는 최소 지점부터 X가 끝나는 최대지점 값을 활용해

      해당 부분만 출력

      => 행의 시작부터 순회(++)하면서 X가 있으면 해당 행의 정보 rs, cs변수에 저장하고 return

      ​ 행의 끝(R-1)부터 순회(–)하면서 X가 있으면 해당 행의 정보 re, ce변수에 저장하고 return

  3. 코드

    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] = '.';
    				}
    			}
       
    		}
    	}
    }
       
    
  4. 느낀점

    • 반복코드가 많아서 코드 줄 수가 길어졌다. 코드 줄 수를 줄이면서 다른 방법으로 어떻게 효율적으로 풀 수 있을지 확인하기

    • 오류가 났던 부분(*)은 if문을 열고 한줄은 자동 적용되서 if( ) { 여기 부분 } 이렇게 중괄호 치는 것을 잘 처리 안해주니까 return 부분이 if문안으로 들어가지 않아서 에러났었다

      -> if( )로 조건문 열면 한 줄이어도 무조건 중괄호 처리 해주기!

  5. 코드 리뷰한 내용은 (*)로 주석 처리했음!

Leave a comment