这是在TopCoder竞赛中使用的问题。我理解大多数解决方案,它基本上在任何时间点跟踪特定节点的最佳解决方案,并且在到达目标节点时可以输出最佳解决方案。但是,该解决方案使用BFS,我感到困惑,因为似乎可以多次访问同一个节点,所以我只是想了解代码是如何工作的。我知道终止条件,但我们如何确保目的地将保持最佳解决方案,如果没有"访问"对于BFS过程的数组,我们如何确保代码实际上会终止(即使存在终止条件)?我已在下面附上问题陈述和解决方案。
问题陈述
您正在玩一款涉及逃避的视频游戏 来自危险地区。在该区域内有您最难的地区 无法进入,为你所做的每一步都需要1点生命的有害区域 在他们和普通地区,不会以任何方式影响你。你会 从(0,0)开始并且必须仅使用Up,Left,使其达到(500,500) 正确和向下步骤。该地图将作为String []致命地给出 列出DEADLY区域和String []有害列表HARMFUL 区域。每个参数中的元素将格式化为 如下:
输入格式(为清晰起见引用):" X1 Y1 X2 Y2"其中(X1,Y1)是区域的一角,(X2,Y2)是区域的另一角
该地区的角落是包容性界限(即(4,1)及(2,2) 包括4和2之间的x值,以及1和2之间的y值 2包括)。所有未指定的区域都被视为NORMAL。如果 区域与特定方块重叠,然后是哪个区域 最坏的情况生效(例如,死亡+有害=死亡,有害+正常= 有害,有害+有害=有害,死亡+正常=死亡。
每一步的伤害都是根据目的地广场和 不在起始广场上(例如,如果广场(500,500)是有害的 你会踩到它上面的伤害点;如果方形(0,0) 你是否真的有点伤害它的伤害点;这个 类似于DEADLY正方形。)
为了获得你将失去的最少的生命 到达目的地。如果没有路径,则返回-1 目的地。你的角色不允许离开地图(即有 X或Y小于0或大于500)。
#include <iostream>
#include <limits>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <strstream>
using namespace std;
struct node
{
node(int _x, int _y) {x = _x; y = _y;}
int id() const
{
return y*501+x;
}
int x, y;
};
map <int, int> dist;
bool operator<(const node &n1, const node &n2)
{
if (dist[n1.id()] != dist[n2.id()])
return dist[n1.id()] < dist[n2.id()];
return n1.id() < n2.id();
}
class Escape
{
public:
int grid[501][501];
void clear(int x1, int y1, int x2, int y2, int val)
{
int tx;
if (x2 < x1)
{
tx = x1;
x1 = x2;
x2 = tx;
}
if (y2 < y1)
{
tx = y1;
y1 = y2;
y2 = tx;
}
for (int y = y1; y <= y2; y++)
for (int x = x1; x <= x2; x++)
{
grid[y][x] = val;
}
}
void bfs(int srcx, int srcy)
{
node src(srcx, srcy);
set <node> totry;
dist.clear();
dist[src.id()] = 0;
totry.insert(src);
int x = 0;
while (totry.size())
{
srcx = totry.begin()->x;
srcy = totry.begin()->y;
src = node(srcx, srcy);
/* cout
x++;*/
for (int dstx = srcx-1; dstx <= srcx+1; dstx++)
for (int dsty = srcy-1; dsty <= srcy+1; dsty++)
if (dstx >= 0 && dsty >= 0 && dstx <= 500 && dsty <= 500)
if ( (dstx-srcx)*(dstx-srcx) + (dsty-srcy)*(dsty-srcy) == 1)
{
node dest(dstx, dsty);
int length = grid[dsty][dstx];
if (length < 2)
if (!dist.count(dest.id()) || dist[dest.id()] > dist[src.id()] + length)
{
dist[dest.id()] = dist[src.id()] + length;
totry.insert(dest);
}
}
totry.erase(src);
}
}
int lowest(vector<string> harmful, vector<string> deadly)
{
int i;
clear(0,0,500,500, 0);
for (i = 0; i < harmful.size(); i++)
{
istrstream in(harmful[i].c_str());
int x1, y1, x2, y2;
in >> x1 >> y1 >> x2 >> y2;
clear(x1, y1, x2, y2, 1);
}
for (i = 0; i < deadly.size(); i++)
{
istrstream in(deadly[i].c_str());
int x1, y1, x2, y2;
in >> x1 >> y1 >> x2 >> y2;
clear(x1, y1, x2, y2, 2);
}
bfs(0, 0);
node end = node(500,500);
if (!dist.count(end.id()))
return -1;
else
return dist[end.id()];
}
};
答案 0 :(得分:1)
这一行:
if (!dist.count(dest.id()) || dist[dest.id()] > dist[src.id()] + length)
正在说&#34;如果它不在计算的距离图中,或者如果我们找到一条新的更便宜的路径,那就探索位置目标&#34;。这种情况可确保BFS终止。