为SPOJ NAKANJ编写条件块的更简单方法-最小骑士移动

Easier way to write a conditional block for SPOJ NAKANJ - Minimum Knight Moves

本文关键字:方法 移动 骑士 更简单 NAKANJ SPOJ 条件      更新时间:2023-10-16

我正在处理SPOJ问题最小骑士移动。现在,当我检查每个单元格的可能移动以确保骑士不会离开棋盘时,我有一系列条件语句。

 // test initialization of one cell (a1)
    int i = 1; //row: a
    int j = 1; //col: 1
    if (j-2 >= MIN_COL) { // left moves
        if (i+1 <= MAX_ROW) {
            neighbors.push_back(board[i+1][j-2]);
        }
        if (i-1 >= MIN_ROW) {
            neighbors.push_back(board[i-1][j-2]);
        }
    }
    if (j+2 <= MAX_COL) { // right moves
        if (i+1 <= MAX_ROW) {
            neighbors.push_back(board[i+1][j+2]);
        }
        if (i-1 >= MIN_ROW) {
            neighbors.push_back(board[i-1][j+2]);
        }
    }
    if (i+2 <= MAX_ROW) { // up moves
        if (j+1 <= MAX_COL) {
            neighbors.push_back(board[i+2][j+1]);
        }
        if (j-1 >= MIN_COL) {
            neighbors.push_back(board[i+2][j-1]);
        }
    }
    if (i-2 >= MIN_ROW) { // down moves
        if (j+1 <= MAX_COL) {
            neighbors.push_back(board[i-2][j+1]);
        }
        if (j-1 <= MIN_COL) {
            neighbors.push_back(board[i-2][j-1]);
        }
    }

有没有一种更简单的方法可以实现这一点,而不必为所有八个可能的移动硬编码一个条件?我刚刚了解了比特板,并将其作为一种潜在的解决方案进行研究,但现在我更感兴趣的是了解是否有更好的方法来用C++编写上述条件语句块。

您基本上有8段代码来检查位置是否在范围内,如果是,则进行push_back。我会先将其作为一个函数编写,然后调用8次。它可能涉及更多的比较,但我预计优化器会删除大部分比较。

void MyClass::add_new_position(int i, int j)
{
    if (MIN_COL <= j && j <= MAX_COL  &&
        MAX_ROW <= i && i <= MAX_ROW)
    {
        neighbors.push_back(board[i][j]);
    }
}
 // test initialization of one cell (a1)
    int i = 1; //row: a
    int j = 1; //col: 1
    add_new_position(i-1,j-2);
    add_new_position(i+1,j-2);
    add_new_position(i-1,j+2);
    add_new_position(i+1,j+2);
    add_new_position(i-2,j-1);
    add_new_position(i+2,j-1);
    add_new_position(i-2,j+1);
    add_new_position(i+2,j+1);