/ BOJ

BOJ_1063_킹_JAVA

문제 : 킹

링크 : BOJ_1063_킹

접근 방식

킹과 돌의 초기 위치가 주어지고, 주어진 명령어에 따라서 킹을 움직인다. 킹이 움직이는 방향 앞에 돌이 있다면, 킹이 움직이는 방향으로 돌을 같이 움직여준다.

위 규칙을 구현하면 되는 문제이다. 하지만 몇 가지 걸림돌이 있다.

  1. 체스판의 번호와 방향 체스판의 세로줄은 a~h까지, 가로줄은 1~8까지 있다. 배열로 이 문제를 푼다면, 배열의 넘버링에 주의할 필요가 있을 것이고, 또 영어 표기를 넘버링 할 방법도 찾아야 할 것이다. 또한, 가로번호를 셀 때 우리가 흔히 아는 방향인 위에서 아래로 내려가는 것이 아닌, 아래에서 위로 올라가는 부분 또한 고려해야한다.

  2. 입력과 출력 처리 킹과 돌의 좌표가 주어질 때, A1, A2와 같이 각 좌표가 공백으로 구분되지 않고 한 번에 들어온다. BufferedReader로 읽어온다고 하면, 읽어온 문자열을 구분할 방안이 필요하다. 만약 비교를 하는 도중 영어로 넘버링 되는 좌표를 숫자로 바꾸어 처리했다면, 출력할 때 이를 영어로 다시 바꿔주는 것도 잊으면 안된다.

위의 사항을 주의하면 로직 자체는 간단하기 때문에 쉽게 풀이할 수 있다.

풀이 방법

  1. 킹이 움직일 수 있는 방법에 따른 단위벡터 배열을 선언한다.

  2. 킹의 좌표와 돌의 좌표를 읽어와 각각 변수에 저장한다. 세로줄에 대한 좌표를 읽어올 때는 -‘A’를 통해서 문자에 해당하는 정수값으로 저장한다.

  3. 명령어를 읽어들여 명령에 맞게 킹을 이동시킨다. 이동시키는 것의 의미는, 킹의 좌표에 해당 방향의 단위벡터만큼 더해주는 것이다. 킹이 범위 바깥으로 나가는 지 체크하는 것을 고려해야한다. 킹이 돌을 함께 움직이는 경우, 돌의 범위도 벗어나면 안된다는 것에 유의한다.

  4. 모든 명령을 수행시킨 후, 현재 킹의 위치와 돌의 위치를 출력한다. 세로줄에 좌표를 출력할 때는 다시 문자로 출력해야하므로 ‘A’를 더해주고 char로 형변환을 해준다.

소스 코드


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

public class BOJ_1063_킹 {

	// 우 좌 상 하 우상 좌상 우하 좌하 (문제기준)
	static int dir[][] = { { 0, 1 }, { 0, -1 }, { -1, 0 }, { 1, 0 }, { 1, 1 }, { 1, -1 }, { -1, 1 }, { -1, -1 } };

//	static int arr[][];

	static int xK, yK, xS, yS;

	public static void main(String[] args) throws NumberFormatException, IOException {

		// 버퍼드리더로 값 읽어오기
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

//		// 뒤의 8은 a부터 h까지 매칭
//		arr = new int[9][9];

		StringTokenizer st = new StringTokenizer(in.readLine(), " ");

		char[] pos = st.nextToken().toCharArray();

		// 왕의 위치를 1로
		xK = pos[1] - '0';
		yK = pos[0] - 'A' + 1;

		pos = st.nextToken().toCharArray();

		xS = pos[1] - '0';
		yS = pos[0] - 'A' + 1;
//		System.out.println(xK+","+yK);
//		System.out.println(xS+","+yS);
		int N = Integer.parseInt(st.nextToken());
		// 왕 이동할 값 읽어와서 이동시키기
		for (int i = 0; i < N; i++) {
			String command = in.readLine();

			switch (command) {
			case "R":
				// 킹 이동 함수
				move(0);
				break;
			case "L":
				move(1);
				break;
			case "B":
				move(2);
				break;
			case "T":
				move(3);
				break;
			case "RT":
				move(4);
				break;
			case "LT":
				move(5);
				break;
			case "RB":
				move(6);
				break;
			case "LB":
				move(7);
				break;
			}

		}

		System.out.printf("%c%d\n",(char)(yK+'A'-1),xK);
		System.out.printf("%c%d\n",(char)(yS+'A'-1),xS);		
	}

	public static void move(int dirr) {
		int dx = dir[dirr][0];
		int dy = dir[dirr][1];

		// 킹이 이동할 위치가 범위 밖인지 확인
		if (xK + dx > 0 && xK + dx <= 8 && yK + dy > 0 && yK + dy <= 8) {
			// 킹의 위치를 변경할 곳에 돌이 있는지 확인
			if (xK + dx == xS && yK + dy == yS) {
				// 돌이 이동할 위치가 범위 밖인지 확인
				if (xS + dx > 0 && xS + dx <= 8 && yS + dy > 0 && yS + dy <= 8) {
					xK = xK + dx;
					yK = yK + dy;

					xS = xS + dx;
					yS = yS + dy;
				}
			}else{
				xK = xK + dx;
				yK = yK + dy;
			}
		}

	}

}