Coding/알고리즘

[알고리즘 TIL] Q1063(구현)

kangplay 2025. 5. 7. 19:22
문제

https://www.acmicpc.net/problem/1063

트러블슈팅

 

1. 위치 이동 로직의 구조화

처음에는 명령어 하나하나에 대해 일일이 조건을 분기해 위치를 직접 이동시켰다. 하지만 체스판처럼 상하좌우, 대각선 등 이동 방향이 고정된 경우, dx, dy 배열을 활용하면 코드를 훨씬 간결하고 직관적으로 만들 수 있다.
이 방식은 실수를 줄여줄 뿐만 아니라, 방향 추가나 수정이 필요할 때도 유지보수가 훨씬 쉬워진다.

 

2. 예외 처리

이 문제의 핵심은 다양한 예외 상황을 순서에 맞게 처리하는 것이었다. 처음엔 "킹을 먼저 이동시키고 → 이동 후 돌과 위치가 겹치면 → 돌도 이동한다"는 순서로 구현했지만, 이 방식에는 한 가지 큰 문제가 있었다.
만약 돌이 경계를 넘어 이동할 수 없는 상황인데도 킹은 이동한 경우, 결국 킹과 돌이 같은 위치에 겹쳐버리는 문제가 생긴 것이다. 이를 해결하기 위해, 킹과 돌의 이동 가능 여부를 모두 사전에 판단한 뒤, 모든 조건을 만족하는 경우에만 실제 위치를 갱신하도록 수정했다.

 

즉, 킹의 새 위치와 돌의 새 위치를 임시 변수에 저장한 뒤, 조건에 부합할 때만 실제 좌표에 반영하는 방식이다.

구현
import java.io.*;

public class Q1063 {

    static int kingPosRow, rockPosRow, N;
    static int kingPosCol, rockPosCol;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        String[] inputStrArr = br.readLine().split(" ");
        String[] kingPos = inputStrArr[0].split("");
        String[] rockPos = inputStrArr[1].split("");
        N = Integer.parseInt(inputStrArr[2]);
        kingPosCol = kingPos[0].charAt(0);
        rockPosCol = rockPos[0].charAt(0);
        kingPosRow = Integer.parseInt(kingPos[1]);
        rockPosRow = Integer.parseInt(rockPos[1]);

        for (int i = 0; i < N; i++) {
            String inputStr = br.readLine();
            int dx = 0, dy = 0;
            switch (inputStr) {
                case "R":
                    dx = 1;
                    break;
                case "L":
                    dx = -1;
                    break;
                case "B":
                    dy = -1;
                    break;
                case "T":
                    dy = 1;
                    break;
                case "RT":
                    dx = 1;
                    dy = 1;
                    break;
                case "LT":
                    dx = -1;
                    dy = 1;
                    break;
                case "RB":
                    dx = 1;
                    dy = -1;
                    break;
                case "LB":
                    dx = -1;
                    dy = -1;
            }

            int newKingPosCol = kingPosCol + dx;
            int newKingPosRow = kingPosRow + dy;

            //킹이 움직일 수 있는지 판단
            if (newKingPosRow < 1 || newKingPosRow > 8 || newKingPosCol < 'A' || newKingPosCol > 'H') {
                continue;
            }

            //돌이 움직여야하는 상황이면 돌이 움직일 수 있는지 판단
            if (newKingPosRow == rockPosRow && newKingPosCol == rockPosCol){
                int newRockPosCol = rockPosCol + dx;
                int newRockPosRow = rockPosRow + dy;

                if (newRockPosRow < 1 || newRockPosRow > 8 || newRockPosCol < 'A' || newRockPosCol > 'H') {
                    continue;
                }

                rockPosCol = newRockPosCol;
                rockPosRow = newRockPosRow;
            }

            //둘 다 문제 없어야 실제 이동
            kingPosCol = newKingPosCol;
            kingPosRow = newKingPosRow;
        }

        bw.write((char)kingPosCol);
        bw.write(kingPosRow + "\n");
        bw.write((char)rockPosCol);
        bw.write(rockPosRow + "");

        bw.flush();
        bw.close();
        br.close();
    }
}