본문 바로가기
알고리즘문제풀이

[JAVA] 백준 15685 드래곤 커브

by Hindsight.. 2020. 11. 8.

전체 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class bj_15685 {

	static int N;
	static boolean[][] map = new boolean[101][101];

	static int dy[] = { 0, -1, 0, 1 };
	static int dx[] = { 1, 0, -1, 0 };
	static ArrayList<Integer> arr;

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

		int x, y, d, g;
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			x = Integer.parseInt(st.nextToken());
			y = Integer.parseInt(st.nextToken());
			d = Integer.parseInt(st.nextToken());
			g = Integer.parseInt(st.nextToken());
			draw(x, y, d, g); // 드래곤 커브 그리기
		}
//		print();
		System.out.println(cnt()); // 개수 세기
	}

	public static int cnt() {
		int cnt = 0;
		for (int i = 0; i < 100; i++) {
			for (int j = 0; j < 100; j++) {
				if (map[i][j] && map[i + 1][j] && map[i][j + 1] && map[i + 1][j + 1])
					cnt++;
			}
		}
		return cnt;
	}

	public static void print() {
		for (int i = 0; i < 100; i++) {
			for (int y = 0; y < 100; y++) {
				if (map[i][y]) {
					System.out.print("0 ");
				} else
					System.out.print("X ");
			}
			System.out.println();
		}
	}

	public static int rotate(int d) { // 90도 회전 함수 4일 경우에만 0으로 리턴한다
		d++;
		if (d == 4)
			return 0;
		return d;
	}

	public static void draw(int x, int y, int d, int g) {
		arr = new ArrayList<Integer>();
		map[y][x] = true; // 첫 점 찍기
		arr.add(d); // 방향 넣기 (선분의 방향, 벡터)
		
		y += dy[d]; // 0세대 그리기
		x += dx[d];
		map[y][x] = true;
		
		int dir;
		for (int i = 0; i < g; i++) { // 1세대부터 ~
			for (int j = arr.size() - 1; j >= 0; j--) { // 가장 최근에 추가한 벡터부터 가져와 회전시키면서 점을 이동시킨다.
				dir = rotate(arr.get(j));  // 회전
				y += dy[dir];
				x += dx[dir];
				map[y][x] = true; // 점 찍기
				arr.add(dir); // 벡터 추가
			}
		}
	}

}

핵심코드 

	public static void draw(int x, int y, int d, int g) {
		arr = new ArrayList<Integer>();
		map[y][x] = true; // 첫 점 찍기
		arr.add(d); // 방향 넣기 (선분의 방향, 벡터)
		
		y += dy[d]; // 0세대 그리기
		x += dx[d];
		map[y][x] = true;
		
		int dir;
		for (int i = 0; i < g; i++) { // 1세대부터 ~
			for (int j = arr.size() - 1; j >= 0; j--) { // 가장 최근에 추가한 벡터부터 가져와 회전시키면서 점을 이동시킨다.
				dir = rotate(arr.get(j));  // 회전
				y += dy[dir];
				x += dx[dir];
				map[y][x] = true; // 점 찍기
				arr.add(dir); // 벡터 추가
			}
		}
	}

 

 

구현 및 시뮬레이션 문제

처음엔 클래스를 만들어 끝점과 회전할 점을 원점으로 옮기고 (a, b) -> (-b, a)를 이용해 회전해보려고 했지만, 만만치 않았다.

다시 과정을 잘 생각해보니 마지막에 그은 벡터부터 원점까지의 벡터를 90도씩 회전 시키면서 선분을 그려가면 되는 문제였다.

 

구현 자체는 어렵지 않았지만, 그림을 그려가는 방식을 도출해내는 것이 어려웠다.

'알고리즘문제풀이' 카테고리의 다른 글

[Java] 방문 길이  (0) 2021.03.08
[JAVA] 프로그래머스 - 위장  (0) 2020.12.15
[JAVA] 백준 3190 뱀  (0) 2020.10.31
[JAVA] 백준 1507 궁금한 민호  (0) 2020.10.03
[JAVA] Programmers LEVEL1 크레인 인형뽑기  (0) 2020.09.11