복대가리의 개발

[C#] 백준 (알고리즘)/실버 문제

[백준 - C#] 1063번 킹

복대가리 2022. 9. 6. 00:33
728x90

문제링크

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

 

1063번: 킹

8*8크기의 체스판에 왕이 하나 있다. 킹의 현재 위치가 주어진다. 체스판에서 말의 위치는 다음과 같이 주어진다. 알파벳 하나와 숫자 하나로 이루어져 있는데, 알파벳은 열을 상징하고, 숫자는

www.acmicpc.net

 

문제

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

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

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

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

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

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

조건

시간제한 : 2초
메모리 제한 : 128 MB

입력

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

출력

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

 

문제정리

1. 열은 가장 왼쪽 열이 A이고, 가장 오른쪽 열이 H까지 이고, 행은 가장 아래가 1이고 가장 위가 8입니다.
2. 돌과 같은 곳으로 이동할 때는, 돌을 킹이 움직인 방향과 같은 방향으로 한 칸 이동합니다.
3. 킹이나 돌이 체스판 밖으로 나갈 경우에는 그 이동은 건너 뛰고 다음 이동을 합니다.
4. 킹과 돌의 마지막 위치를 구하면 됩니다.

이번 문제의 경우 킹과 돌을 입력받은 방향대로 움직인 후 마지막 위치를 구하는 문제입니다.

저의 경우 계산하기 쉽게 열을 정수로 전부 바꾸어서 체스말과 돌을 이동시켰습니다.

처음 입력 받을 때 'A' + 1을 해주어 입력받은 값이 'A'라면 1로 변형 시키고 'B'라면 2로 변형시켰습니다.

 

입력받은 방향의 경우에도 정수로 변형하여 이동시켰으며 킹을 이동시키고 체스판을 벗어났다면 다시 원래대로 돌리고 다음 이동을 진행하도록 하였습니다.

 

돌의 경우 킹이 이동 한 후 같은 위치라면 돌을 입력받은 방향으로 이동 시킨 후 체스판을 벗어났는지 검사를 진행하고 체스판을 벗어났다면 킹과 돌의 위치를 원래대로 이동하고 다음 이동을 진행합니다.

 

주의할 점으로는 돌의 위치는 킹과 같을 때만 이동하며 돌이 체스판을 벗어나면 킹도 위치를 원래대로 돌려야 한다는 것입니다.

 

이번 문제의 경우 방향을 이동해야될 경우가 헷갈려서 고생을 하였지만 차분히 문제를 풀어 내었습니다. 

아래의 코드를 천천히 따라가다보면 쉽게 풀이를 하실 수 있으실 것 같습니다.

 

C# 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
static void Main(string[] args)
{
    StreamWriter writer = new StreamWriter(Console.OpenStandardOutput());
    StreamReader reader = new StreamReader(Console.OpenStandardInput());
 
    string[] input = reader.ReadLine().Split();
 
    // 킹과 돌을 정수로 입력 받습니다. 
    (int row, int colum) king = (int.Parse(input[0][1].ToString()), input[0][0- 'A' + 1);
    (int row, int colum) stone = (int.Parse(input[1][1].ToString()), input[1][0- 'A' + 1);
 
    int N = int.Parse(input[2]);
 
    for (int i = 0; i < N; i++)
    {
        // 입력 받은 이동해야될 방향을 정수로 변경합니다.
        (int row, int colum) = FindDir(reader.ReadLine());
 
        // 킹을 이동시킵니다.
        king = (king.row + row, king.colum + colum);
 
        // 킹이 체스판을 벗어난다면 다시 원래대로 이동시키고 다음 이동을 진행합니다.
        if (king.row >= 9 || king.colum >= 9 || king.row <= 0 || king.colum <= 0)
        {
            king = (king.row - row, king.colum - colum);
            continue;
        }
 
        // 킹과 돌의 위치가 같다면 돌을 킹이 움직인 방향으로 똑같이 움직입니다
        if (king.row == stone.row && king.colum == stone.colum)
            stone = (stone.row + row, stone.colum + colum);
 
        // 돌의 위치가 체스판을 벗어난다면 돌과 킹을 원래대로 돌립니다.
        if (stone.row >= 9 || stone.colum >= 9 || stone.row <= 0 || stone.colum <= 0)
        {
            stone = (stone.row - row, stone.colum - colum);
            king = (king.row - row, king.colum - colum);
        }
    }
 
    writer.WriteLine($"{(char)(king.colum + 'A' - 1)}{king.row}");
    writer.WriteLine($"{(char)(stone.colum + 'A' - 1)}{stone.row}");
 
    writer.Close();
    reader.Close();
 
    (int row, int colum) FindDir(string input)
        => input switch
        {
            "R" => (01),
            "L" => (0-1),
            "B" => (-10),
            "T" => (10),
            "RT" => (11),
            "LT" => (1-1),
            "RB" => (-11),
            "LB" => (-1-1),
            _ => throw new NotImplementedException(),
        };
}
cs
읽어주셔서 감사합니다 오늘도 즐거운 하루 되세요.

 

728x90