TopCoder" Escape"解决方案混乱

时间:2015-06-24 13:38:59

标签: c++ algorithm breadth-first-search

这是在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()];
}

};

1 个答案:

答案 0 :(得分:1)

这一行:

if (!dist.count(dest.id()) || dist[dest.id()] > dist[src.id()] + length)

正在说&#34;如果它不在计算的距离图中,或者如果我们找到一条新的更便宜的路径,那就探索位置目标&#34;。这种情况可确保BFS终止。