BOJ_1063_킹_JAVA
문제 : 킹
링크 : BOJ_1063_킹
접근 방식
킹과 돌의 초기 위치가 주어지고, 주어진 명령어에 따라서 킹을 움직인다. 킹이 움직이는 방향 앞에 돌이 있다면, 킹이 움직이는 방향으로 돌을 같이 움직여준다.
위 규칙을 구현하면 되는 문제이다. 하지만 몇 가지 걸림돌이 있다.
-
체스판의 번호와 방향 체스판의 세로줄은 a~h까지, 가로줄은 1~8까지 있다. 배열로 이 문제를 푼다면, 배열의 넘버링에 주의할 필요가 있을 것이고, 또 영어 표기를 넘버링 할 방법도 찾아야 할 것이다. 또한, 가로번호를 셀 때 우리가 흔히 아는 방향인 위에서 아래로 내려가는 것이 아닌, 아래에서 위로 올라가는 부분 또한 고려해야한다.
-
입력과 출력 처리 킹과 돌의 좌표가 주어질 때, A1, A2와 같이 각 좌표가 공백으로 구분되지 않고 한 번에 들어온다. BufferedReader로 읽어온다고 하면, 읽어온 문자열을 구분할 방안이 필요하다. 만약 비교를 하는 도중 영어로 넘버링 되는 좌표를 숫자로 바꾸어 처리했다면, 출력할 때 이를 영어로 다시 바꿔주는 것도 잊으면 안된다.
위의 사항을 주의하면 로직 자체는 간단하기 때문에 쉽게 풀이할 수 있다.
풀이 방법
-
킹이 움직일 수 있는 방법에 따른 단위벡터 배열을 선언한다.
-
킹의 좌표와 돌의 좌표를 읽어와 각각 변수에 저장한다. 세로줄에 대한 좌표를 읽어올 때는 -‘A’를 통해서 문자에 해당하는 정수값으로 저장한다.
-
명령어를 읽어들여 명령에 맞게 킹을 이동시킨다. 이동시키는 것의 의미는, 킹의 좌표에 해당 방향의 단위벡터만큼 더해주는 것이다. 킹이 범위 바깥으로 나가는 지 체크하는 것을 고려해야한다. 킹이 돌을 함께 움직이는 경우, 돌의 범위도 벗어나면 안된다는 것에 유의한다.
-
모든 명령을 수행시킨 후, 현재 킹의 위치와 돌의 위치를 출력한다. 세로줄에 좌표를 출력할 때는 다시 문자로 출력해야하므로 ‘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;
}
}
}
}