문제: https://www.acmicpc.net/problem/1783
알고리즘 분류: 많은 조건 분기, 그리디 알고리즘, 구현
병든 나이트🐴가 체스판에서 최대한 많은 칸을 방문하는 문제
주요 조건:
1. N × M 크기의 체스판에서 가장 왼쪽 아래 칸에서 시작
2. 병든 나이트는 4가지 이동 방법만 가능
이동 횟수 + 1
N = 1
또는 M = 1
인 경우:
체스판이 한 줄짜리면 시작 위치 외에 더 이동할 수 없으므로 1을 반환
N = 2
인 경우:
세로가 2칸인 경우 1칸 위로, 2칸 오른쪽
과 1칸 아래로, 2칸 오른쪽
두 가지 방법만 사용 가능
➡️ 이 경우 가로로 최대 (M+1)/2
칸까지 이동 가능하지만, 4번까지만 허용 됨
N ≥ 3
, M < 7
인 경우:
가로 길이가 충분하지 않아 제약 조건을 만족하기 어려운 경우
최대 M개 칸까지 방문 가능하지만, 4칸으로 제한 됨
N ≥ 3
, M ≥ 7
인 경우:
충분히 큰 체스판에서는 모든 이동 방법을 한 번씩 사용하고 나서도 최적의 방법으로 이동 가능
모든 이동 방법을 한 번씩 사용하면 오른쪽으로 총 6칸 이동하게 됨
그 후로는 1칸 위, 2칸 오른쪽
과 1칸 아래, 2칸 오른쪽
을 번갈아 사용하여 오른쪽으로 이동
➡️ 결과적으로 M-2
개의 칸을 방문할 수 있음
const fs = require('fs');
const [N, M] = fs.readFileSync('/dev/stdin').toString().trim().split(' ').map(Number);
function solution(N, M) {
// 시작 위치 포함하여 최소 1개의 칸은 방문
if (N === 1 || M === 1) {
return 1;
}
// 세로 길이가 1 초과, 가로 길이가 1일 때는 방문할 수 없음
if (N > 1 && M === 1) {
return 1;
}
// 세로 길이가 2일 때는 특별한 경우
if (N === 2) {
// 가로로 움직일 수 있는 최대 횟수 (1칸 위로, 2칸 오른쪽 / 1칸 아래로, 2칸 오른쪽만 사용 가능)
// 이동 횟수는 (M-1)/2 이하이고 최대 4회까지 가능
return Math.min(4, Math.floor((M + 1) / 2));
}
// N >= 3, M < 7인 경우 최대 4칸까지만 이동 가능
if (M < 7) {
return Math.min(4, M);
}
// 일반적인 경우, N >= 3, M >= 7
// 4번 이상 이동할 때 모든 이동 방법을 한 번씩 사용해야 함
// 모든 이동 방법을 한 번씩 사용하면 오른쪽으로 총 6칸 이동
// 그 후로는 1칸 위, 2칸 오른쪽 + 1칸 아래, 2칸 오른쪽 조합으로 반복
return M - 2;
}
console.log(solution(N, M));
참고
https://bedecked-operation-4d1.notion.site/99-10-TIL-1783-1d2eb405261e803fb153f95bec2f86a1