※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 6601번 문제인 Knight Moves이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/6601
6601번: Knight Moves
A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visits each square of a given set of n squares on a chessboard exactly once. He thinks that the most difficult part
www.acmicpc.net
체스판의 각 칸에서 다른 칸까지 knight가 움직여야하는 각 최소횟수를 Floyd-Warshall을 이용해 전처리하는 것으로 문제를 간단히 해결하자. 체스판의 크기가 충분히 작으므로 Floyd-Warshall이 아닌 다른 방식(BFS 등)을 이용해 전처리를 하여도 무방할 것으로 보인다.
격자판 위에서 상하좌우의 움직임을 이용하여 탐색을 할 때 크기 4의 dr과 dc(또는 dx와 dy)배열을 이용해 간단히 구현할 수 있듯이 나이트의 움직임도 크기 8의 배열을 이용해 아래와 같이 편리하게 구현할 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int dist[64][64];
int dr[8] = { 1,2,2,1,-1,-2,-2,-1 };
int dc[8] = { 2,1,-1,-2,-2,-1,1,2 };
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
memset(dist, 0x3f, sizeof(dist));
for (int r = 0; r < 8; r++) {
for (int c = 0; c < 8; c++) {
int cur = r * 8 + c;
for (int i = 0; i < 8; i++) {
int rr = r + dr[i], cc = c + dc[i];
if (-1 < rr && rr < 8 && -1 < cc && cc < 8) dist[cur][rr * 8 + cc] = 1;
}
}
}
for (int k = 0; k < 64; k++) dist[k][k] = 0;
for (int k = 0; k < 64; k++) {
for (int r = 0; r < 64; r++) {
for (int c = 0; c < 64; c++) {
dist[r][c] = min(dist[r][c], dist[r][k] + dist[k][c]);
}
}
}
string s1, s2;
while (cin >> s1 >> s2) {
int x = (s1[0] - 'a') * 8 + (s1[1] - '1'), y = (s2[0] - 'a') * 8 + (s2[1] - '1');
cout << "To get from " << s1 << " to " << s2 << " takes " << dist[x][y] << " knight moves.\n";
}
}
'BOJ' 카테고리의 다른 글
[BOJ 6602 // C++] Eeny Meeny Moo (0) | 2023.01.12 |
---|---|
[BOJ 15828 // C++] Router (0) | 2023.01.12 |
[BOJ 26933 // C++] Receptet (0) | 2023.01.11 |
[BOJ 26947 // C++] Klockan (0) | 2023.01.11 |
[BOJ 26905 // C++] Sortera spellistan (0) | 2023.01.11 |