[백준 15685] 드래곤 커브(Java)

최민길(Gale)·2023년 1월 24일
1

알고리즘

목록 보기
22/172

문제 링크 : https://www.acmicpc.net/problem/15685

이 문제는 드래곤 커브 작성의 규칙성을 찾아내면 풀 수 있습니다.

이 문제의 가장 어려운 부분이 바로 드래곤 커브의 규칙성을 찾아내는 것인데요, 각 케이스 별로 나눠보면 다음과 같습니다.

(기존 / 신규)
1. 1세대 : 0 / 1
2. 2세대 : 0,1 / 2,1
3. 3세대 : 0,1,2,1 / 2,3,2,1
...

위의 수열을 확인해보면 새롭게 추가되는 드래곤 커브의 경우 기존 세대의 방향의 역순의 +1 이 된다는 것을 확인할 수 있습니다. 여기서 하나 더 유의할 점은 방향값이 3을 초과할 경우 다시 0으로 회귀하는 성질을 가지고 있기 때문에 (기존 세대의 방향의 역순의 +1)%4 라는 공식을 얻을 수 있습니다.

해당 정보를 토대로 0세대부터 g세대까지 모든 점을 체크하여 구현하시면 됩니다.

다음은 코드입니다.

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

public class Main{

    static int N;
    static int res = 0;
    static boolean[][] req = new boolean[101][101];
    static int[] dx = {1,0,-1,0};
    static int[] dy = {0,-1,0,1};

    static void checkSquare(){
        for(int i=0;i<100;i++){
            for(int j=0;j<100;j++){
                boolean a = req[i][j];
                boolean b = req[i+1][j];
                boolean c = req[i+1][j+1];
                boolean d = req[i][j+1];

                if(a && b && c && d) res++;
            }
        }
    }

    static void draw(int x, int y, int d, int g){
        // 현재 위치 체크
        req[y][x] = true;

        // 방향 저장
        ArrayList<Integer> direction = new ArrayList<>();

        // 현재 방향이 가리키는 끝점 체크
        int nx = x + dx[d];
        int ny = y + dy[d];
        req[ny][nx] = true;

        // 현재 방향 배열이 저장
        direction.add(d);

        // 세대를 진행하면서 이에 따른 방향의 끝값 체크
        // 새로운 세대 방향 설정 규칙
        // 기존 세대의 방향의 역순의 +1
        while(g-- >0){
            // 방향의 역순
            for(int i=direction.size()-1;i>=0;i--){
                // 새로운 세대 방향 = 기존 세대 방향의 역순의 +1
                // 이 때 방향이 3에서 0으로 넘어가므로 4의 나머지로 처리해주어야 함
                int nd = (direction.get(i)+1)%4;
                nx = nx + dx[nd];
                ny = ny + dy[nd];
                req[ny][nx] = true;
                direction.add(nd);
            }
        }
    }

    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());

        for(int i=0;i<N;i++){
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            int d = Integer.parseInt(st.nextToken());
            int g = Integer.parseInt(st.nextToken());
            draw(x,y,d,g);
        }

        checkSquare();
        System.out.println(res);
    }
}

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글

관련 채용 정보