구름 LEVEL JAVA - 구름 찾기 깃발 (난이도 2)

» algorithm

구름 난이도 2 구름 찾기 깃발

문제 요약

  1. 한 변의 길이가 N인 격자 모양의 게임판에 구름이 있으면 [1], 없으면 [0]인 게임판이있다.
  2. 구름이 없는 칸에 [상하, 좌우, 대각선]에 있는 구름의 개수를 깃발에 표시한다.
  3. K 인 깃발의 개수는 총 몇개인가?

폭탄 구현하기(2) 와 비슷해서 나름 쉬웠다.

코드

import java.io.*;
import java.util.*;

class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine() , " ");
        int N = Integer.parseInt(st.nextToken());   // 게임판 크기
        int K = Integer.parseInt(st.nextToken());   // 깃발에 적힌 숫자

        char[][] ground = new char[N + 1][N + 1];
        char[][] score = new char[N + 1][N + 1];

        // 게임판 셋팅
        for(int i=1; i<=N; i++) {
            st = new StringTokenizer(br.readLine() , " ");
            for(int j=1; j<=N; j++) {
                ground[i][j] = st.nextToken().charAt(0);
            }
        }

        // 상하 좌우 대각선
        int[] tb = {1 , 1 ,  1 , 0 ,  0 , -1 , -1 , -1};
        int[] lr = {1 , 0 , -1 , 1 , -1 ,  1 ,  0 , -1};

        // 구름 체크
        for(int i=1; i<=N; i++) {
            for(int j=1; j<=N; j++) {

                // 구름이 없는 곳 일 때만
                if( ground[i][j] == '0' ) {
                    // 상하 좌우 대각선에 구름 있는지 체크
                    for(int k=0; k<8; k++) {
                        int tempX = i + tb[k];
                        int tempY = j + lr[k];

                        // 있는 칸 일때만
                        if(aroundCheck(tempX , tempY , N)) {
                            // 인접한 칸에 구름 있음
                            if(ground[tempX][tempY] == '1') {
                                score[i][j]++;
                            }
                        }
                    }
                }

            }
        }

        // K와 같은 수가 적힌 깃발의 개수 체크
        int result = 0;
        for(int i=1; i<=N; i++) {
            for (int j = 1; j <= N; j++) {
                if(K == score[i][j]) {
                    result++;
                }
            }
        }

        System.out.println(result);
    }
    
    // 인접한 칸이 실제로 있는지 체크
    public static boolean aroundCheck(int x, int y, int ground) {
        return x > 0 && x <= ground && y > 0 && y <= ground;
    }
}

풀이

  1. 게임판, 깃발점수를 게임판 길이+1 만큼 2차원 배열로 먼저 생성.
    +1 해주는 이유는 인접한 칸을 체크하기 위함.
    입력받은대로 배열을 생성 시 그 범위를 벗어나거나,
    제대로 된 측정을 할 수 없다.
  2. 입력받은 게임판 길이(N) 만큼 for 문을 돌며(세로) 구름이 있는지 입력 받는다.
  3. 다시 for 문을 돌며(가로) 입력받은 숫자(구름)를 세팅해준다.
  4. [상하(2), 좌우(2), 대각선(4)]을 체크 하기위해 총 8개의 1차원 배열을 생성.
  5. 게임칸 길이(N) 만큼 이중 for 문을 돌며 해당 칸에 구름이 없을 시 다시 for 문을 사용해 인접한 칸에 구름이 있는지 체크.
  6. 있을 시 해당 칸의 깃발 점수 증가.
  7. 최종 이중 for 문을 돌려 K 와 숫자와 같은 깃발의 점수가 몇개인지 확인.