算法/方法

时间:2014-09-02 00:08:49

标签: algorithm

最近我遇到了这个问题,我不知道在哪里或如何开始解决它。这是一个问题:

  

有8个雕像0,1,2,3,4,5,6,7。每个雕像指向以下四个方向之一的北,南,东或西。约翰想安排雕像,以便他们都指向同一个方向。然而约翰仅限于以下8个动作,这些动作对应于每个雕像顺时针旋转90度的旋转。 (N到E,E到S,S到W,W到N)

     

移到

     

A:0,1

     

B:0,1,2

     

C:1,4,5,6

     

D:2,5

     

E:3,5

     

F:3,7

     

G:5,7

     

H:6,7

     

帮助约翰找出最少数量的动作来帮助将所有雕像指向一个方向。

     

输入:由8个字符组成的字符串初始值。每个字符都是' N,' E,' W'

     

输出:表示最少的整数。需要将雕像安排在同一方向。如果没有可能的序列,则返回-1。

     

示例测试用例:

     

输入:SSSSSSSS

     

输出:0

     

说明:所有雕像都指向同一方向。所以它需要0次移动

     

测试案例1:

     

输入:WWNNNNNN

     

输出:1

     

Exp:John可以使用Move A,这将使所有雕像指向North

     

测试案例3:

     

输入:NNSEWSWN

     

输出:6

     

Exp:John使用Move A两次,B一次,F两次,G一次。这将导致所有雕像面临W。

我能想到的唯一方法是暴力破解它。但由于移动可以多次完成(测试用例3),在我们断定这种安排不可能(即输出-1)之前应用移动的限制是什么?我正在寻找可用于解决此问题的特定类型的算法,以及用于识别算法的问题的哪一部分。

5 个答案:

答案 0 :(得分:2)

请注意,移动的顺序没有区别,只有 set (重复)。另请注意,进行4次相同的移动相当于什么都不做,所以从来没有任何理由让同样的移动超过3次。这将空间减少到4 8 可能的序列,这不是太可怕,但我们仍然可以比蛮力更好。

  1. 对待0和1的唯一不同的举动是C,所以应用C多次,以使0和1对齐。我们不能再使用C,并且C是唯一可以移动4的东西,所以剩下的任务是将所有内容对齐到4。
  2. 移动6的唯一方法是H;应用H对齐6。
  3. 现在对齐3和7.我们可以用E和G来做,但我们可以选择使用F作为捷径。 F移动的最佳数量尚不清楚,因此我们将使用E和G,稍后再回到F.
  4. 应用D对齐5。
  5. 应用B对齐2。
  6. 应用A以对齐0和1。
  7. 现在重新访问F,看看快捷方式是否真的可以保存动作。选择最佳的F移动数。 (即使蛮力也很容易,因为只有4种可能性可以测试。)

答案 1 :(得分:2)

转向操作的N,E,W,S方向与Z mod 4 succ一致:转N = (succ 0) mod 4,转W = (succ succ 2) mod 4

每次移动都是一个零(无变化)和一个(一个一个)被添加到输入的向量:假设你有你的NNSEWSWN的例子,它是[0, 0, 2, 1, 3, 2, 3, 0],你按下按钮A,这是[1, 1, 0, 0, 0, 0, 0, 0],产生[1, 1, 2, 1, 3, 2, 3, 0]或EESEWSWN。

现在如果你做了很多不同的操作,他们都会加起来。因此,您可以使用此矩阵方程表示整个系统:

(start + move_matrix * applied_moves) mod 4 = finish

其中startfinish是如上所述的位置向量,move_matrix 8x8矩阵包含所有移动,applied_moves 8元素向量表示多少次我们按下每个按钮(范围0..3)。

从此,你可以得到:

applied_moves = (inverse(move_matrix) * (finish - start)) mod 4

应用移动的数量就是这样:

num_applied_moves = sum((inverse(move_matrix) * (finish - start)) mod 4)

现在只需插入finish的四个不同值,然后查看哪个值最少。

你可以使用matlab,numpy,octave,APL,无论你的船是什么岩石,只要它支持矩阵代数,就能非常快速而且非常容易地得到答案。

答案 2 :(得分:0)

这听起来有点像家庭作业......但我会选择这种逻辑。

运行循环,查看将所有雕像移动到一个方向所需的移动次数。你会得到类似allEast = 30,allWest = 5等的东西。取最低的总和,相应的方向就是答案。有了这种心态,很容易构建一个算法来处理计算。

答案 3 :(得分:0)

蛮力可行。应用4次的移动与完全不应用移动相同,因此每次移动只能应用0次,1次,2次或3次。

移动的顺序无关紧要。移动a后跟b与b后跟a相同。

因此,只有4 ^ 8 = 65536种可能的移动组合。

答案 4 :(得分:0)

一般解决方案是注意只有4 ^ 8 = 64k不同的配置。因此,每个移动可以表示为64k 2字节索引的表,其中一个配置到下一个。例如2个字节被分成8个2比特字段0 = N,1 = E,2 = S,3 = W.此外,我们可以再使用一个比特表来说明64k配置中的哪一个具有指向同一方向的所有雕像。

这些表格不需要在运行时计算。它们可以在编写程序时进行预处理并存储。

让表A [c]给出在将移动A应用到配置c之后得到的配置。如果c是成功的配置,则Z [c]返回true。

所以我们可以使用一种BFS:

1. Let C be a set of configurations, initially C = { s } where s is the starting config
2. Let n = 0 
3. If Z[c] is true for any c in C, return n
4. Let C' be the result of applying A, B, ... H to each element of C.  
5. Set C = C', n = n + 1 and go to 3
从理论上讲,C的大小可以增长到近64k,但它越大,成功的机会就越大,所以在实践中这应该是相当快的。