[BAEKJOON] 백준 1063: 킹 (C#)

2024. 6. 1. 12:05IT/BaekJoon

문제 링크

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

 

 

문제

8*8크기의 체스판에 왕이 하나 있다. 킹의 현재 위치가 주어진다. 체스판에서 말의 위치는 다음과 같이 주어진다. 알파벳 하나와 숫자 하나로 이루어져 있는데, 알파벳은 열을 상징하고, 숫자는 행을 상징한다. 열은 가장 왼쪽 열이 A이고, 가장 오른쪽 열이 H까지 이고, 행은 가장 아래가 1이고 가장 위가 8이다. 예를 들어, 왼쪽 아래 코너는 A1이고, 그 오른쪽 칸은 B1이다.

킹은 다음과 같이 움직일 수 있다.

  • R : 한 칸 오른쪽으로
  • L : 한 칸 왼쪽으로
  • B : 한 칸 아래로
  • T : 한 칸 위로
  • RT : 오른쪽 위 대각선으로
  • LT : 왼쪽 위 대각선으로
  • RB : 오른쪽 아래 대각선으로
  • LB : 왼쪽 아래 대각선으로

체스판에는 돌이 하나 있는데, 돌과 같은 곳으로 이동할 때는, 돌을 킹이 움직인 방향과 같은 방향으로 한 칸 이동시킨다. 아래 그림을 참고하자.

입력으로 킹이 어떻게 움직여야 하는지 주어진다. 입력으로 주어진 대로 움직여서 킹이나 돌이 체스판 밖으로 나갈 경우에는 그 이동은 건너 뛰고 다음 이동을 한다.

킹과 돌의 마지막 위치를 구하는 프로그램을 작성하시오.

 

 

입력

첫째 줄에 킹의 위치, 돌의 위치, 움직이는 횟수 N이 주어진다. 둘째 줄부터 N개의 줄에는 킹이 어떻게 움직여야 하는지 주어진다. N은 50보다 작거나 같은 자연수이고, 움직이는 정보는 위에 쓰여 있는 8가지 중 하나이다.

 

 

출력

첫째 줄에 킹의 마지막 위치, 둘째 줄에 돌의 마지막 위치를 출력한다.

 

 

 

통과한 답안

namespace _1063
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string[] inputs = Console.ReadLine().Split(' ');
            string king = inputs[0];
            string stone = inputs[1];
            int N = int.Parse(inputs[2]);

            int[] kingPos = { king[0] - 'A', king[1] - '1' };
            int[] stonePos = { stone[0] - 'A', stone[1] - '1' };

            Dictionary<string, int[]> moves = new Dictionary<string, int[]>
            {
                {"R" , new int[] {  1,  0 } },
                {"L" , new int[] { -1,  0 } },
                {"B" , new int[] {  0, -1 } },
                {"T" , new int[] {  0,  1 } },
                {"RT", new int[] {  1,  1 } },
                {"LT", new int[] { -1,  1 } },
                {"RB", new int[] {  1, -1 } },
                {"LB", new int[] { -1, -1 } },
            };

            for (int i = 0; i < N; i++)
            {
                string move = Console.ReadLine();

                int[] moveVector = moves[move];
                int newKingX = kingPos[0] + moveVector[0];
                int newKingY = kingPos[1] + moveVector[1];

                if (InBoard(newKingX, newKingY))
                {
                    if (newKingX == stonePos[0] && newKingY == stonePos[1])
                    {
                        int newStoneX = stonePos[0] + moveVector[0];
                        int newStoneY = stonePos[1] + moveVector[1];
                        if (InBoard(newStoneX, newStoneY))
                        {
                            kingPos[0] = newKingX;
                            kingPos[1] = newKingY;
                            stonePos[0] = newStoneX;
                            stonePos[1] = newStoneY;
                        }
                    }
                    else
                    {
                        kingPos[0] = newKingX;
                        kingPos[1] = newKingY;
                    }
                }
            }

            Console.WriteLine($"{(char)(kingPos[0] + 'A')}{kingPos[1] + 1}");
            Console.WriteLine($"{(char)(stonePos[0] + 'A')}{stonePos[1] + 1}");
        }

        static bool InBoard(int x, int y)
        {
            return x >= 0 && x < 8 && y >= 0 && y < 8;
        }
    }
}

 

8X8 크기의 체스판에 킹과 돌이 있을 때,

주어진 조건에 따라서 킹을 움직이는 코드를 작성하는 문제이다.

 

킹의 움직임은 총 8개로 이를 moves라는 dictionary를 이용하여 구현하였다.

또, 움직임 이후에 체스판 안에 있는지를 판단할 InBorad 메서드 구현하여

주어진 입력에 대한 킹의 움직임을 구현하였다.

 

단, 이 문제의 특이점으로는 킹을 움직였을 때, 돌이 그 위치에 있다면

돌을 킹이 움직이는 방향으로 같이 움직이게 구현해야 되기 때문에

킹의 움직임의 방향을 moveVector로 저장하고,

킹이 움직이는 위치에 돌이 있는지 판단하여

돌이 있다면 돌도 함께 움직이도록 구현하였다.

 

 

주어진 조건이 까다로운(돌이 있다면 돌도 움직이고, 체스판을 벗어나지 않게) 문제이지만,

조건에 맞춰서 움직일 수 있는 최적의 자료구조 등을 이용하여 구현할 수 있던 문제였다.