알고리즘/백준

[백준/c++] 18404번: 현명한 나이트

녕이 2022. 2. 12. 21:47
728x90

 

 

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

 

18404번: 현명한 나이트

첫째 줄에 N과 M이 공백을 기준으로 구분되어 자연수로 주어진다. (1 ≤ N ≤ 500, 1 ≤ M ≤ 1,000) 둘째 줄에 나이트의 위치 (X, Y)를 의미하는 X와 Y가 공백을 기준으로 구분되어 자연수로 주어진다. (

www.acmicpc.net

 

문제 요약

 

NxN 체스판의 특정 위치에 하나의 나이트

M개의 상대편 말들의 위치 값이 주어졌을 때, 각 상대편 말을 잡기 위한 나이트의 최소 이동 수 계산하는 프로그램

 

[이동 방법]

현재 나이트 위치 (X, Y)

(X-2, Y-1), (X-2, Y+1), (X-1, Y-2), (X-1, Y+2), (X+1, Y-2), (X+1, Y+2), (X+2, Y-1), (X+2, Y+1)

 

모든 말들의 위치는 중복 X, 나이트가 도달할 수 있는 위치로만 주어진다.

 

 

범위

 

체스판 크기 N, 말 개수 M(1 ≤ N ≤ 500, 1 ≤ M ≤ 1,000)

나이트 위치 X, Y (1 ≤ X, Y  N) 

말 위치 A, B (1 ≤ A, B  N)

 

 


 

 

상대편 말을 잡기 위한 최소 이동 수 = 최단 거리 = BFS

각 말들의 위치(A, B)를 BFS의 시작점으로 넣어주면 된다. 

 

✨ 체스판과 같이 좌표가 찍히는 문제는 꼭 1부터 시작해야 하는지 확인하자.

 

#include <iostream>
#include <queue>
using namespace std;
int n, m, X, Y, dist[502][502];
int dir[8][2] = {{-2,-1}, {-2,1}, {-1,-2}, {-1,2}, {1,-2}, {1,2}, {2,-1}, {2,1}};

void input(){
    cin >> n >> m;
    cin >> X >> Y;
}

void BFS(){
    for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) dist[i][j] = -1;
    queue<pair<int, int>> q;
    q.push({X, Y});
    dist[X][Y] = 0;
    while(!q.empty()){
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for(int i=0; i<8; i++){
            int dx = x + dir[i][0];
            int dy = y + dir[i][1];
            if(dx < 1 || dy < 1 || dx > n || dy > n) continue; //경로이탈 pass
            if(dist[dx][dy] != -1) continue;                   //방문한 곳 pass
            dist[dx][dy] = dist[x][y] + 1;
            q.push({dx, dy});
        }
    }
}

int main(){
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    input();
    BFS();
    for(int i=0; i<m; i++) {
        int horseX, horseY;
        cin >> horseX >> horseY;
        cout << dist[horseX][horseY] << ' ';
    }
    cout << '\n';
    return 0;
}

 

 

 

 

💡공부 및 기록용 블로그이므로 오류가 있을 수 있습니다.💡

만약 문제에 오류나 오타가 있다면 댓글로 알려주세요
언제나 환영합니다. 감사합니다. 화이팅!

 

 

 

 

728x90