2024. 1. 19. 13:17ㆍ알고리즘
문제
행복 왕국의 왕실 정원은 체스판과 같은 8 x 8 좌표 평면이다. 왕실 정원의 특정한 한 칸에 나이트가 서 있다. 나이트는 매우 충성스러운 신하로서 매일 무술을 연마한다.
나이트는 말을 타고 있기 때문에 이동을 할 때는 L자 형태로만 이동할 수 있으며 정원 밖으로는 나갈 수 없다. 나이트는 특정한 위치에서 다음과 같은 2가지 경우로 이동할 수 있다.
- 수평으로 두 칸 이동한 뒤에 수직으로 한 칸 이동하기
- 수직으로 두 칸 이동한 뒤에 수평으로 한 칸 이동하기
이처럼 8 x 8 좌표 평면상에서 나이트의 위치가 주어졌을 때 나이트가 이동할 수 있는 경우의 수를 출력하는 프로그램을 작성하시오. 이때 왕실의 정원에서 행 위치를 표현할 때는 1부터 8로 표현하며, 열 위치를 표현할 때는 a부터 h로 표현한다.
입력 조건
- 첫째 줄에 8 x 8 좌표 평면상에서 현재 나이트가 위치한 곳의 좌표를 나타내는 두 문자로 구성된 문자열이 입력된다. 입력 문자는 a1처럼 열과 행으로 이뤄진다.
출력 조건
- 첫째 줄에 나이트가 이동할 수 있는 경우의 수를 출력하시오.
ex) 입력이 a1이면 출력이 2이다.
왜냐하면 a1에서는 오른쪽으로나 위쪽으로는 이동이 불가능하여, (2, -1), (-1, -2)로 이동할 수 있어 c2나 b3으로만 이 동 가능하기 때문이다.
동빈님 + 나의 풀이 방식
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String word = scanner.next();
int x = word.charAt(1) - '0';
int y = word.charAt(0) - 'a' + 1;
int[] nx = { -2, -2, 2, 2, -1, -1, 1, 1};
int[] ny = { 1, -1, 1, -1, 2, -2, 2, -2};
int count = 0;
for( int i=0; i<nx.length; i++){
int new_x = x + nx[i];
int new_y = y + ny[i];
if( new_x <= 8 || new_y <= 8 || new_x >= 1 || new_y >= 1 )
count++;
}
System.out.print(count);
}
}
이번에는 동빈님과 풀이 방식이 비슷하지만 완벽하게 구현하지 못해서 동빈님의 풀이를 가져왔다.
"왕실의 나이트"는 "상하좌우"와 문제 풀이 방식이 유사하다.
우선 사용자로부터 문자열을 입력받는다. 예를 들어 a1 같은 것이다.
문자열 중에서 x행과 y열을 분리해준다.
x행은 "a1" 중에서 "1"에 해당한다. 따라서 word.charAt(1)으로 두 번째 요소를 추출해줘야 한다.
그 다음에는 -'0'을 해준다. 이 과정은 char형을 int형으로 바꾸기 위해서 실행된다.
그렇다면 -'1'도 있고, '2'도 있는데, 왜 '0'을 해줄까?
이유는 입력받은 x값을 그래도 추출하기 위해서다.
예를 들어 입력 값이 '5'라면 '5' - '0' = '5'가 된다.
y열은 "a1" 중에서 "a"에 해당한다. 따라서 word.charAt(0)으로 첫 번째 요소를 추출해줘야 한다.
그 다음에는 -'a' + 1을 해준다. 이 과정 또한 char형을 int형으로 바꾸기 위해서 실행된다.
그렇다면 왜 -'a'를 한 다음에 +1을 해줄까?
이유는 열은 'a' 행부터 시작하기 때문이다.
만약 사용자로부터 입력받은 열의 값이 'a'라면, 'a' - 'a'를 하면 0이 된다.
따라서 올바른 값을 추출하기 위해서는 +1을 해주어야 한다. 그러면 1열, 2열, 3열..로 추출 가능하다.
그리고 nx 배열, ny 배열에 각각 값들을 넣어준다.
이동할 수 있는 범위는 (왼쪽으로 한 칸, 위로 두 칸), (오른쪽으로 한 칸, 위로 두 칸), (왼쪽으로 한 칸, 아래로 두 칸), (오른쪽으로 한 칸, 아래로 두 칸), (왼쪽으로 두 칸, 위로 한 칸), (왼쪽으로 두 칸, 아래로 한 칸), (오른쪽으로 두 칸, 위로 한 칸), (오른쪽으로 두 칸, 아래로 한 칸) 이렇게 총 8가지이다.
이것을 인덱스로 표현하면 (-2, 2), (2, 2), (-1, -2), (1, -2), (-2, 1), (-2, -1), (2, 1), (2, -1)이 된다.
이를 분리하면 int[] nx = { -2, 2, -1, 1, -2, -2, 2, 2 }와 int[] ny = {2, 2, -2, -2, 1, -1, 1, -1}이 된다.
이 값들을 순회하며 넣어주되, x와 y가 값을 벗어나지 않는 경우( 1 <= x,y <= 8 )에 있으면 경우의 수로 체크해주면 된다.
'알고리즘' 카테고리의 다른 글
[이코테 with Java] 음료수 얼려 먹기(DFS) (0) | 2024.01.23 |
---|---|
[이코테 with Java] 게임 개발(구현) (0) | 2024.01.22 |
[이코테 with Java] 시각(구현) (1) | 2024.01.19 |
[이코테 with Java] 상하좌우(구현) (0) | 2024.01.18 |
[이코테 with Java] 숫자 카드 게임(그리디 알고리즘) (0) | 2024.01.18 |