코딩테스트/백준
[Java] 백준 15685번 - 드래곤 커브
곰돌이볼
2023. 3. 10. 09:43
- 문제
- 드래곤 커브의 꼭짓점으로 만들 수 있는 1x1 크기의 정사각형의 개수 구하기
- 조건
- 0세대 드래곤 : x 또는 y 방향으로 1칸 이동
- 다음 세대 드래곤 : 이전 세대의 마지막 시점에서 이때까지 이동한 경로를 시계방향 90도로 회전시킨만큼 이
- 100 x 100 격자 안에만 드래곤 커브가 존재한다.
- 0 ≤ x ≤ 100
- 0 ≤ y ≤ 100
- 입력
- 첫번째 줄 : 드래곤 커브의 개수 N
- 두번째 줄 ~ N+1번쨰 줄 : x y d g
- 드래곤 커브의 시작 시점 x y
- 드래곤의 시작방향 d
- 0 : x방향 →
- 1 : y방향 ↑
- 2 : x방향 ←
- 3 : y방향 ↓
- g세대
- 찾아낸 규칙
- 다음 세대로 갈 때 마지막 위치에서 시계방향 90도 회전하면 이전 회전방향의 역순서대로 반시계방향의 90도로 회전한다.
- 0세대 드래곤 커브 : →
- 1세대 드래곤 커브 : → | ↑
- 2세대 드래곤 커브 : → ↑ | ← ↑
- 3세대 드래곤 커브 : → ↑ ← ↑ | ← ↓ ← ↑
- 다음 세대로 갈 때 마지막 위치에서 시계방향 90도 회전하면 이전 회전방향의 역순서대로 반시계방향의 90도로 회전한다.
- 로직 1)
- ArrayList인 dir에 이전 세대의 방향을 저장
- 현세대의 방향은 이전 세대의 방향 역순으로 반시계방향 90도 회전 방향으로 dir에 추가하기
- g세대에 도달하면 멈추기
- 회전 방향 dir을 이용해서 배열 xy에 좌표값 입력하기
- 배열 xy를 통해서 직사각형 개수 찾기
import java.io.*;
import java.util.*;
// 드래곤 커브
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int count = Integer.valueOf(br.readLine()); // 드래곤 커브의 개수
int answer = 0; // 정사각형의 개수
boolean[][] xy = new boolean[101][101]; // xy 좌표계 (초기값 : false)
// xy 좌표 (오른쪽, 위쪽, 왼쪽, 아래쪽)
int[] x = new int[]{1, 0, -1, 0};
int[] y = new int[]{0, -1, 0, 1};
for(int i=0; i<count; i++) { // 드래곤 커브의 개수만큼 반복
String[] dragon = br.readLine().split(" ");
int current_x = Integer.valueOf(dragon[0]); // 시작위치의 x좌표
int current_y = Integer.valueOf(dragon[1]); // 시작위치의 y좌표
int gen = Integer.valueOf(dragon[3]); // 세대수
// 드래곤 커브의 방향
List<Integer> dir = new ArrayList<>();
// 드래곤 커브의 이동 좌표
dir.add(Integer.valueOf(dragon[2])); // 시작 방향 추가
xy[current_x][current_y] = true; // 시작 좌표
current_x = current_x + x[dir.get(0)];
current_y = current_y + y[dir.get(0)];
xy[current_x][current_y] = true; // 이동 좌표
if(gen != 0) rotate(dir, xy, current_x, current_y, gen); // 재귀호출
}
// 사각형 여부 확인하기
for(int i=0; i<xy.length-1; i++) {
for(int j=0; j<xy[i].length-1; j++) {
if(xy[i][j] && xy[i+1][j] && xy[i][j+1] && xy[i+1][j+1]) answer++;
}
}
System.out.println(answer);
}
// 현재 list의 역순으로 반시계방향 90도 회전한 방향을 list에 추가하기 && 이동 좌표값 true로 변경
// 0 : 오른쪽, 1 : 위쪽, 2 : 왼족, 3 : 아래쪽
public static void rotate(List<Integer> dir, boolean[][] xy, int current_x, int current_y, int gen) {
// xy 좌표 (오른쪽, 위쪽, 왼쪽, 아래쪽)
int[] x = new int[]{1, 0, -1, 0};
int[] y = new int[]{0, -1, 0, 1};
for(int i = dir.size()-1; i>=0; i--) {
int d = (dir.get(i)+1)%4; // 현재 이동 방향
// 현재 list의 역순으로 반시계방향 90도 회전한 방향을 list에 추가하기
dir.add(d);
// 이동 좌표값 true로 변경
current_x = current_x + x[d];
current_y = current_y + y[d];
xy[current_x][current_y] = true;
}
if(--gen > 0) rotate(dir, xy, current_x, current_y, gen);
}
}
- 결과
- 성공