UVA-439-骑士动作。出现运行时错误的原因应该是什么?

时间:2019-08-25 18:32:30

标签: c++

我正在尝试使用C++ 5.3.0 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE

解决uva问题编号'439-Knight Moves'

但是我一直在遇到运行时错误,而我实际上不知道是什么导致了此错误。 请注意,我是c ++的新手。 这是我的代码。我已经尝试通过bfs搜索来解决此问题。

#include <iostream>
#include <queue>
#include <cstdio>

using namespace std;

string s1,s2;

struct pos{
    int x,y,move;
};

bool isValid(pos point){
    if(point.x <= 0 || point.y <= 0 || point.x > 8 || point.y > 8)
        return false;
    return true;
}
pos createPosition(int x,int y,int move){
    pos newpos;
    newpos.x = x;
    newpos.y = y;
    newpos.move = move;

    return newpos;
}

void BFS(pos src,pos dst){
    queue<pos> pendingQueue;
    pendingQueue.push(src);
    bool visited[9][9];
    for(int i=0;i<9;i++)
       for(int j=0;j<9;j++)
          visited[i][j] = false;

    while(!pendingQueue.empty()){
        pos currentPosition = pendingQueue.front();
        pendingQueue.pop();
        visited[currentPosition.x][currentPosition.y] = true;
        if(currentPosition.x == dst.x && currentPosition.y == dst.y){
            cout << "To get from " << s1 << " to " << s2 << " takes " << currentPosition.move <<" knight moves.\n";

            break;
        }
        pos new_positions[8];
        new_positions[0] = createPosition(currentPosition.x - 1, currentPosition.y - 2 ,currentPosition.move + 1);
        new_positions[1] = createPosition(currentPosition.x - 2, currentPosition.y - 1 ,currentPosition.move + 1);
        new_positions[2] = createPosition(currentPosition.x - 2, currentPosition.y + 1 ,currentPosition.move + 1);
        new_positions[3] = createPosition(currentPosition.x - 1, currentPosition.y + 2 ,currentPosition.move + 1);
        new_positions[4] = createPosition(currentPosition.x + 1, currentPosition.y + 2 ,currentPosition.move + 1);
        new_positions[5] = createPosition(currentPosition.x + 2, currentPosition.y + 1 ,currentPosition.move + 1);
        new_positions[6] = createPosition(currentPosition.x + 2, currentPosition.y - 1 ,currentPosition.move + 1);
        new_positions[7] = createPosition(currentPosition.x + 1, currentPosition.y - 2 ,currentPosition.move + 1);


        for(int i=0;i<8;i++){
            if(isValid(new_positions[i]) && !visited[new_positions[i].x][new_positions[i].y]){
                pendingQueue.push(new_positions[i]);
                visited[new_positions[i].x][new_positions[i].y] = true;
            }
        }
    }
}

int main(){

    while(cin >> s1 >> s2){
        int r1,c1,r2,c2;
        r1 = s1[0] - 'a' + 1;
        c1 = s1[1] - '0';
        r2 = s2[0] - 'a' + 1;
        c2 = s2[1] - '0';
        pos src = createPosition(r1,c1,0);
        pos dst = createPosition(r2,c2,0);

        BFS(src,dst);
    }

}

我不知道如何解决此运行时错误,而且我无处不在问这个问题。希望有人能在这里帮助我。

问题的链接是 Here

2 个答案:

答案 0 :(得分:1)

if(!visited[new_positions[i].x][new_positions[i].y == dst.y){-由于您从未初始化visited ,因此不会飞起来。

您从未初始化visited的成员,因此它们具有不确定的值,并且读取它们的值为undefined behaviour。 当然,您将一些元素(有时)设置为true,但其他元素是什么?它们不是神奇的false

如果您希望visited的成员以false开头(看来),那么必须将其初始化为该值。

答案 1 :(得分:1)

您在Jasper Juhlanswered之后编辑了问题,初始化了visited,但是嵌套循环不是必需的:

bool visited[8][8] = {}; // Or since C++11:  bool visited[8][8]{};

您还解决了WhozCraigvisited从8x8扩展到9x9所指出的索引不一致问题。更好的方法是修改isValid和初始转换,以保留从0开始的索引。在以下代码段中,我将这些检查封装在pos类中。

#include <iostream>
#include <queue>
#include <stdexcept>

struct pos
{
    int x, y, move{};
    pos(int xx, int yy, int m)
        : x{xx}, y{yy}, move{m}
    {}
    pos(std::string const& str)
    {
        if ( str.size() != 2 )
            throw std::runtime_error("Invalid input size");
        x = str[0] - 'a';   // from  'a', 'b', ..., 'h'  to  0, 1, ..., 7
        y = str[1] - '1';   // from  '1', '2', ..., '8'  to  0, 1, ..., 7
        if ( is_not_valid() )
            throw std::runtime_error("Invalid input coordinates");
    }
    bool is_not_valid()
    {
        return  x < 0  ||  x > 7  ||  y < 0  ||  y > 7;
    }
};

int BFS(pos src, pos dst)
{
    constexpr int x_moves[] = {-1, -2, -2, -1,  1,  2,  2,  1},
                  y_moves[] = {-2, -1,  1,  2,  2,  1, -1, -2};
    bool visited[8][8]{};

    if(src.x == dst.x && src.y == dst.y)
        return 0;

    std::queue<pos> pendingQueue;
    pendingQueue.push(src);   
    visited[src.y][src.x] = true;

    while(!pendingQueue.empty())
    {
        pos current_position = pendingQueue.front();
        pendingQueue.pop();

        for (int i = 0; i < 8; ++i)
        {
            pos new_position {current_position.x + x_moves[i], 
                              current_position.y + y_moves[i],
                              current_position.move + 1};

            if ( new_position.is_not_valid()  ||  visited[new_position.y][new_position.x] )
                continue;

            if( new_position.x == dst.x  && new_position.y == dst.y)
                return new_position.move;

            pendingQueue.push(new_position);
            visited[new_position.y][new_position.x] = true;
        }
    }
    throw std::runtime_error("Sorry, I can't find a solution");
}

int main()
{
    std::string source, dest;
    while(std::cin >> source >> dest)
    {
        try
        {
            std::cout << "To get from " << source << " to " << dest
                      << " takes " << BFS(source, dest) << " knight moves.\n";
        }
        catch(std::exception const& e)
        {
            std::cerr << e.what() << ".\n";
        }
    }
}

可测试的here