【问题标题】:computing points by determine the neighbors algorithm通过确定邻居算法计算点
【发布时间】:2021-01-07 19:43:36
【问题描述】:

我正在用 C++ 编写有关检查向量值的编码挑战。 我已经被困在这个挑战上几个小时了,我想不出一个合适的解决方案。 我有一个称为值的向量,看起来像这样:

std::vector <char > values {a,b,a,b,b,b,a,a,a,a,b,b,a};

然后在三个值之后开始一列,所以最后应该如何看待这些值:

abaaa
bbab 
abab

玩家 1 有字母 a,玩家 2 有字母 b。如果玩家一具有正交连接的 a(不包括对角线 a),他将获得积分。如果一个 a 不与任何其他玩家连接,则玩家 1 获得一分。两个 a 值 2 分,3 a 值 5 分。总是排除对角线 a's。如果连接的 a's 超过 3 个,则玩家 1 额外获得 2 分。例如 4 a 的 7 分和 5 a 是 9 分。这也适用于玩家 2。棘手的部分是玩家可以获得不止一组正交连接的 a 或 b 的分数。例如,如果玩家 1 有一组 3 个 a,他得到 5 分。如果他也有一个a,他会得到一分。所以最后他一共得到6分。

abaaa 
bbab 
abab

玩家 1 得到:9+1+1

玩家 2 得到:7+2

我希望我的问题很清楚。 如果我能使用任何提示或算法,我将不胜感激。

我真的不知道如何开始。

【问题讨论】:

  • 听起来需要flood fill algorithm
  • 或者深度优先搜索算法。目前想不出任何其他算法。
  • 我之前没有听说过洪水填充算法,但类似的方法是找到所有连接的组件。我们有一条从一个节点到它的四个主要邻居中的任何一个的边,如果主要邻居具有与该节点相等的值。处理后,我们只需要计算每个连通分量的大小和关联的值,并将计算的分数加到对应的玩家身上。首先将输入字符串重新格式化为二维网格可能会有所帮助,但如果你很聪明,可以将原始字符串作为图形遍历。
  • @john 我检查了洪水填充算法的实现,它们使用多维向量。它也适用于一维向量吗?
  • @konoha 除非我误解了,否则 概念上 你有 2D 结构,即使你实际上是把它放在 1D 向量中。因此,只要您可以在一维向量中计算出上、下、左、右相邻位置(以及边缘所在的位置),您就可以执行洪水填充操作。 (例如,通过将 3 添加到当前索引来完成向左移动)。

标签: c++ algorithm vector


【解决方案1】:

Flood fill是一种N维数组区域填充算法。它被例如使用图像编辑软件中的桶填充工具可以用新颜色填充相似颜色的区域。它可以用几乎任何图搜索算法(DFS、BFS 等)来实现。它也非常类似于在 e.g. 中使用的数组搜索算法的类型。视频游戏,以找到 AI 与其目标之间的最短路径(除了在洪水填充中,您不必对标记进行编号,因为它们与原点的距离被遍历以计算实际路径)。

基本前提是:

  1. 将令牌计数器设置为零。选择一个尚未“填充”的记号(可能为向量中的每个记号跟踪一个布尔“填充”标志),并记录其字符。
  2. 将令牌标记为“已填充”并增加令牌计数器。
  3. 在与标记相邻的所有正交方向上搜索(在这种情况下最多四个;如果您位于二维数组的“边缘”,则少于四个)。对于这些相邻标记中的每一个,如果它们尚未被填充,并且如果它们与当前讨论的字符相同的字符(在步骤 1 中记录),则从第 2 步开始对它们进行递归(或者只是将它们推入堆栈/队列并迭代,分别在 DFS/BFS 中是传统的)。您也可以在递归函数的开头而不是在调用递归函数之前进行此条件检查,就像 Wikipedia 的示例所做的那样。如果是递归,请确保为递归调用提供对令牌计数器的(非常量)引用,以便所有递归调用都增加相同的令牌计数器。
  4. 一旦所有递归调用完成,这意味着在步骤 1 中选择的令牌的搜索分支已经完成。此时,存储在令牌计数器中的值表示与步骤 1 中选择的令牌正交连接的令牌的数量。所有这些连接的令牌现在都被标记为“已填充”。确定与令牌计数器中的值相关的“分数”,并将其添加到正确玩家的分数中(取决于步骤 1 中记录的角色)。
  5. 从第 1 步开始重复,直到所有标记都标记为“已填充”。

引用的维基百科页面还提供了递归函数的伪代码。

当然,您得到的是一维数组(向量)而不是二维。话虽如此,您可以使用一些基本的条件逻辑将 2D 运动转换为 1D 运动。例如,您可以通过简单地沿一维数组向前遍历三个单元(假设一列中有 3 个元素)沿理论二维数组“向右”遍历一个单元。这个逻辑的其余部分可以留给读者作为练习(注意数组“边缘”)。

或者,您可以通过简单地“重塑”一维数组将其转换为二维数组,如有必要,将“墓碑”(占位符)留在最后一列的空白处。默认情况下将墓碑标记为“已填充”,以便它们永远不会被遍历。

【讨论】:

    猜你喜欢
    • 2020-06-21
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 2012-04-27
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多