UVaOJ 439 - Knight Moves

本文提供了一种使用广度优先搜索(BFS)算法解决国际象棋中马从一点到另一点最少步数的问题。通过定义状态结构、边界条件判断和搜索过程,实现对棋盘上任意两点之间的最短路径计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

——by A Code Rabbit


Description

下国际象棋,输入棋盘上的两个格子的坐标,输出马从一点走到另一点的最少步数。


Types

Date Structure :: Graphs


Analysis

经典的 BFS 题目,注意马不可以走到棋盘外,即要注意边界条件的判断。


Solution

// UVaOJ 439
// Knight Moves
// by A Code Rabbit

#include <cstdio>
#include <cstring>

struct Status {
    int x;
    int y;
    int num_steps;
};

struct Change {
    int x;
    int y;
};

const Change CHANGE[] = {
              {-2, -1},        {-2, 1},
    {-1, -2},                           {-1, 2},

    { 1, -2},                           { 1, 2},    
              { 2, -1},        { 2, 1},
};

const int LIMITS = 10;
char a_col, a_row;
char b_col, b_row;

bool is_visited[LIMITS][LIMITS];
Status queue[LIMITS * LIMITS];
int target_x, target_y;
int head, tail;
int ans;
bool is_found;

void INIT();
void BFS();
void Search(int x, int y, int num_steps);

int main() {
    while (scanf("%c%c %c%c", &a_col, &a_row, &b_col, &b_row) != EOF) {
        getchar();
        // BFS.
        BFS();
        // Outputs.
        printf("To get from %c%c to %c%c takes %d knight moves.\n", a_col, a_row, b_col, b_row, ans);
    }

    return 0;
}

void INIT() {
    memset(is_visited, 0, sizeof(is_visited));
    head = 0;
    tail = 1;
    queue[0].x = a_row - '0';
    queue[0].y = a_col - 'a';
    queue[0].num_steps = 0;
    target_x = b_row - '0';
    target_y = b_col - 'a';
    is_found = false;
} 

void BFS() {
    // Judge special sentence.
    if (a_row == b_row
     && a_col == b_col) {
        ans = 0;
        return;
    }
    // INIT.
    INIT();
    // BFS.
    while (head < tail) {
        for (int i = 0; i < 8; i++) {
            Search(queue[head].x + CHANGE[i].x, queue[head].y + CHANGE[i].y, queue[head].num_steps + 1);
        }
        head++;
    }
}

void Search(int x, int y, int num_steps) {
    // Exit.
    if (is_found) {
        return;
    }
    if (x <= 0 || x > 8
     || y < 0 || y >= 8) {
        return;
    }
    if (is_visited[x][y]) {
        return;
    }
    // Judge whether is the target.
    if (x == target_x
     && y == target_y) {
        ans = num_steps;
        is_found = true;
        return;
    }
    // Continue.
    queue[tail].x = x;
    queue[tail].y = y;
    queue[tail].num_steps = num_steps;
    is_visited[x][y] = true;
    tail++;
}


下载PDF

参考资料:无

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值