- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
这是来自 Facebook 招聘样本测试的问题。
有K个钉子。当从钉子的底部到顶部看时,每个钉子可以按半径递减的顺序固定圆盘。有 N 个圆盘,半径为 1 到 N;给定钉子的初始配置和钉子的最终配置,输出从初始配置转换为最终配置所需的移动。您需要以最少的移动次数完成转换。
移动包括拾取任何一个桩子的最上面的圆盘并将其放在任何其他桩子的顶部。在任何时候,都必须保持所有钉子的递减半径特性。
Constraints:
1<=N<=8
3<= K<=5
Input Format:
NK
第二行包含 N 个整数。每个整数都在 1 到 K 的范围内,其中第 i 个整数表示初始配置中半径为 i 的圆盘所在的桩。
第三行以类似于初始配置的格式表示最终配置。
Output Format:
第一行包含 M - 完成转换所需的最少移动数。
接下来的 M 行描述了一个移动,通过一个要从中选择的 Hook 编号和一个要放置的 Hook 编号。如果有多个解决方案,输出其中任何一个就足够了。您可以假设,总有一个少于 7 步的解决方案,并且初始配置不会与最终配置相同。
Sample Input #00:
2 3
1 1
2 2
Sample Output #00:
3
1 3
1 2
3 2
Sample Input #01:
6 4
4 2 4 3 1 1
1 1 1 1 1 1
Sample Output #01:
5
3 1
4 3
4 1
2 1
3 1
讨论这个问题的解决方案没有什么坏处,因为它是一个示例问题。
经典的汉诺塔问题的解决方案非常易于编写代码:
void hanoi(char s, char i, char d, int n)
{
if(n>0)
{
hanoi(s, d, i, n-1);
cout<<s<<":"<<d<<endl;
hanoi(i, s, d, n-1);
}
}
以上内容也可以扩展到河内的一般“k”钉塔。但是,事实证明,这些知识对于设计这个示例难题的解决方案毫无用处。对于将来如何处理此类问题和类似问题有什么建议吗?
最佳答案
这是我的动态规划解决方案,最多可在 O(K^N) 步中找到最佳移动顺序,它在 K = 5、N = 8 的情况下运行不到一秒。由于懒惰,我对输入数据进行了硬编码.
它是一个通过状态空间的 BFS,永远不会访问同一个状态两次。然后通过从头到头回溯得到实际路径(这部分与最优序列的长度成线性关系)。基本上,它是“通过迷宫的最短路径”算法,但“迷宫”是问题的状态空间,起始“位置”是初始状态,结束“位置”是期望状态。
许多类似的问题都可以通过这种方式解决,只要您可以定义一个有限状态空间,您的目标是最小化两个状态之间的“距离”,以及一种计算可以从状态移动到哪些状态的方法当前状态。
例如,任意数量的“传教士和食人者”问题都可以用相同的算法解决。
此外,如果您需要“所有最优解”而不是“任何最优解”,则很容易修改算法以提供它们。
class Program
{
static int N = 8;
static int K = 5;
static List<int> StartState = new List<int> { 3, 3, 2, 1, 4, 1, 5, 2 };
static List<int> EndState = new List<int> { 1, 4, 2, 2, 3, 4, 4, 3 };
static LinkedList<int> StateQueue = new LinkedList<int>();
static int[] MovesToState = new int[(int)Math.Pow(K, N)];
static void Main(string[] args)
{
for (int i = 0; i < StartState.Count; i++)
{
StartState[i]--;
EndState[i]--;
}
int startStateIndex = StateToNum(StartState);
int endStateIndex = StateToNum(EndState);
for (int i = 0; i < MovesToState.Length; i++)
MovesToState[i] = -1;
MovesToState[startStateIndex] = 0;
StateQueue.AddFirst(startStateIndex);
while (StateQueue.Count > 0 && MovesToState[endStateIndex] == -1)
{
var legalMoves = LegalMoves(StateQueue.Last.Value);
foreach (var newStateIndex in legalMoves)
{
int currMoves = MovesToState[StateQueue.Last.Value];
if (MovesToState[newStateIndex] == -1)
{
MovesToState[newStateIndex] = currMoves + 1;
StateQueue.AddFirst(newStateIndex);
}
}
StateQueue.RemoveLast();
}
var currStateIndex = endStateIndex;
var moves = new List<Tuple<int, int>>();
while (currStateIndex != startStateIndex)
{
var legalMoves = LegalMoves(currStateIndex);
int currMoves = MovesToState[currStateIndex];
foreach (var prevStateIndex in legalMoves)
{
if (MovesToState[prevStateIndex] == MovesToState[currStateIndex] - 1)
{
var currState = NumToState(currStateIndex);
var prevState = NumToState(prevStateIndex);
for (int i = 0; i < N; i++)
{
if (currState[i] != prevState[i])
{
moves.Add(new Tuple<int, int>(prevState[i] + 1, currState[i] + 1));
currStateIndex = prevStateIndex;
break;
}
}
}
}
}
Console.WriteLine(MovesToState[endStateIndex]);
moves.Reverse();
foreach (var move in moves)
{
Console.WriteLine("{0} {1}", move.Item1, move.Item2);
}
Console.Read();
}
static List<int> LegalMoves(int stateIndex)
{
var legalMoves = new List<int>();
var state = NumToState(stateIndex);
int[] minOnPeg = new int[K];
for (int i = 0; i < minOnPeg.Length; i++)
minOnPeg[i] = N;
for (int i = 0; i < N; i++)
for (int j = 0; j < K; j++)
if (state[i] == j && i < minOnPeg[j])
minOnPeg[j] = i;
bool[] isTop = new bool[N];
for (int i = 0; i < isTop.Length; i++)
isTop[i] = false;
for (int i = 0; i < K; i++)
if (minOnPeg[i] < N)
isTop[minOnPeg[i]] = true;
for (int i = 0; i < N; i++)
{
if (!isTop[i])
continue;
for (int j = 0; j < K; j++)
{
if (minOnPeg[j] <= i)
continue;
var tmp = state[i];
state[i] = j;
var newStateIndex = StateToNum(state);
legalMoves.Add(newStateIndex);
state[i] = tmp;
}
}
return legalMoves;
}
static int StateToNum(List<int> state)
{
int r = 0;
int f = 1;
foreach (var peg in state)
{
r += f * peg;
f *= K;
}
return r;
}
static List<int> NumToState(int num)
{
var r = new List<int>();
for (int i = 0; i < N; i++)
{
r.Add(num % K);
num = num / K;
}
return r;
}
}
关于Facebook 示例拼图 : Towers of Hanoi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16601701/
我在某处遇到了以下难题 #include int main() { { /*Fill in something here to make this code compile
我正在尝试为 iOS 创建一个拼图游戏应用程序。从我在互联网上的搜索来看,确实没有任何关于这个主题的教程。有谁知道任何人都知道的好教程或游戏教程的链接?谢谢。顺便说一下,iOS4 将不胜感激。 最佳答
如果必须使用 Promises,您会如何编写以下代码? 这个想法是,“私有(private)”方法 p1 调用一个执行异步操作的函数,然后,当异步调用的结果准备就绪时,控制权将传递给“私有(priva
下面是其中一个 facebook 谜题:我无法理解如何进行此操作。 你有 C 个容器、B 个黑球和无限数量的白球。您希望以一种方式在容器之间分配球,即每个容器至少包含一个球,并且选择白球的概率大于或等
有 5 位成员围坐在一张 table 旁。关键值是坐在 table 周围的成员数量。所以现在关键值将是 5。一个恐怖分子告诉成员,因为你们是 5 个成员,所以我将从第一个成员开始数,数到 5 的人将被
你能在不抛出错误的情况下解决这个问题吗?答案是单线。这是来自一个死的职位发布,在回复中要求回答。我认为这是剔除受访者的聪明方法,但我似乎无法在不出错的情况下回答它。 显而易见的解决方案: f.moo(
此源输出 G'Day Mate. 这是怎么发生的? public static void main(String args[]) { System.out.println("Hello Wor
我正在 android 中开发一个 slider 拼图,它有一个图像被分解成小图像,我们需要对这些 fragment 进行排序以形成正确的图像。我使用了一个 3x3 的 GridView ,其中包含
我遇到了以下难题,无法在 Picat 中制定解决方案: You will generate 5-digit numbers, where each digit is in 1..5 and diffe
我是 Javascript 新手,并且正在努力解决 CodeWars 中的这个难题。 约翰想用壁纸装饰房间。房间的尺寸为:宽度(w)、高度(h)、长度(l)。一卷壁纸的尺寸为 52cm 宽,10m 长
我对 Java 还很陌生,尝试过 Best Before puzzle from Spotify昨天。当我发送它时,我收到“错误答案”错误。检查其他解决方案没有帮助,我无法弄清楚哪个输入给出了错误的答
我正在尝试恢复我拥有的一些旧代码,这是一个拼图游戏。它从文件夹中加载图像(拼图),将它们随机放置在页面周围,然后拖放到板上。这曾经有效,但当我今天尝试使用它时,它只是抛出错误(见下文)。 HTML:
这对你们来说可能是个愚蠢的问题。它是关于 CSS Sprites 的。我有一个包含 4 个菜单的导航,例如 .. HOME COMPANY SERVICES SUPPORT 尽管我使用了一个 css
我需要创建一个标题,可以根据正在构建的页面轻松添加或删除部分,但我在处理其中一部分时遇到了问题。 我有一个标题,看起来像这样将所有组件放在 如果导航被移除,它应该看起来像这样(垂直居中) 我的问题是如
我在 JS 中构建了一个 15 拼图,但我的随机拼图生成正在创建无法解决的拼图实例。这可能是因为我不是计算机科学专业的负责人,但我不确定如何计算代码排列中的反转次数。我想知道如何编写我的代码,以便我可
我正在寻找 8 Puzzle graphs tree generator,最好是 (php+) html+css+javascript。我需要的是类似 3 2 1 6 8 7 5 4 会生成所有可
我住在德国,在 Android Market 上发布“Last Call Widget”。随着时间的推移,我一直在稳步改进它,但一组用户仍然提示它无法在他们的设备上运行。 我的小部件监听“androi
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我正在尝试制作一个看起来像这样的拼图游戏。我试过的看起来像这样。 https://jsfiddle.net/uccfb46z/ 现在如果我想改变碎片的形状我需要修改这部分 - outside: fu
首先,让我为缺少 SSCCE 表示歉意。我在这方面真的没有足够的专业知识来弄清楚什么是相关的,什么不是。 简而言之,问题是在两台运行相同分辨率 (1366x768) 的不同计算机上,我女朋友的 tum
我是一名优秀的程序员,十分优秀!