给定一个蛇和梯子游戏,编写一个函数,返回最小跳跃数量,以获取顶部或目标位置。 你可以假设你抛出的结果总是对你有利
**
这是我的解决方案,但不确定它是否正确。
这个问题类似于数组中的青蛙跳跃。但在此之前我们 必须以该格式对问题进行建模。
创建一个大小为100的数组,如果存在则为每个位置存储6创建 没有蛇或梯子。店铺跳数。如果梯子出现在那里 点。如果存在蛇,则存储-ve在该位置跳转。
现在我们必须解决我们可以达到的最小步数。 在O(n ^ 2)时间内使用动态编程可以解决主要问题 复杂性和O(n)空间。
答案 0 :(得分:5)
查看this博客文章,它使用蒙特卡罗模拟和马尔可夫链对滑槽和梯子进行全面的数学分析。他确实展示了一种计算获胜步数的方法(基本上构建一个转换矩阵,看看你必须将起始矢量乘以多少次才能得到一个非零最终位置的解)。这可能不是最有效的方式,但这篇文章非常值得一读。
这是python中使用sets的快速解决方案。我从博客文章中获得了跳转表中的数字。在每一步,它只是计算从上一步可以到达的所有位置,并继续这样做,直到最终位置在可到达的位置之中:
jumps = {1: 38, 4: 14, 9: 31, 21: 42, 28: 84, 36: 44, 51: 67, 71: 91, 80: 100,
98: 78, 95: 75, 93: 73, 87: 24, 64: 60, 62: 19, 56: 53, 49: 11, 48: 26, 16: 6}
final_pos = 100
positions = {0} #initial position off the board
nsteps = 0
while final_pos not in positions:
nsteps += 1
old_positions = positions
positions = set()
for pos in old_positions:
for dice in range(1, 7):
new_pos = pos + dice
positions.add(jumps.get(new_pos, new_pos))
print 'Reached finish in %i steps' % nsteps
执行时间可以忽略不计,并且会发出7的正确答案(见博客)。
答案 1 :(得分:3)
这是Python中一个简单的广度优先搜索解决方案:
# the target square and the positions of the snakes and ladders:
top = 100
jump = { 1: 38, 4: 14, 9: 31, 16: 6, 21: 42, 28: 84, 36: 44,
48: 26, 49: 11, 51: 67, 56: 53, 62: 19, 64: 60, 71: 91,
80:100, 87: 24, 93: 73, 95: 75, 98: 78}
# start from square 0 (= outside the board) after 0 rolls
open = {0}
path = {0: ()}
while len(open) > 0:
i = open.pop()
p = path[i] + (i,)
for j in xrange(i+1, i+7):
if j > top: break
if j in jump: j = jump[j]
if j not in path or len(path[j]) > len(p):
open.add(j)
path[j] = p
for i in path:
print "Square", i, "can be reached in", len(path[i]), "rolls via", path[i]
电路板布局(即jump
字典)取自他在blog post中由Bas Swinckels链接的answer。
此代码将打印(其中一条)最短路径到板上每个可到达的方块,结束于:
Square 100 can be reached in 7 rolls via (0, 38, 41, 45, 67, 68, 74)
如果您想要完整输出,请参阅this demo on ideone.com。
答案 2 :(得分:1)
我在C#中实现了这一点。你可以查看我的要点here。我还会粘贴下面的代码。
在我的实施中,我考虑了以下几点:
最短路识别:当算法到达目标时,它将注册最短路径,在计算过程中,它将丢弃比当前找到的解决方案更长的搜索。这使得在复杂情况下该过程更快。
using System;
using System.Collections.Generic;
using System.Linq;
namespace SnakeAndLaddersSolution
{
public class SnakeAndLadder
{
private struct Jump
{
public int Start;
public int End;
}
private const int TOP = 100;
private const int STEP_SIZE = 6;
private int _minDiceCount = int.MaxValue;
private readonly List<Jump> _jumps = new List<Jump>();
public bool OptionalJump { get; set; }
public void AddJump(int start, int end)
{
_jumps.Add(new Jump { Start = start, End = end });
}
public int Solve()
{
var path = new Stack<int>();
path.Push(1); //start from square 1
return FindMinimumDice(path, 0);
}
private int FindMinimumDice(Stack<int> path, int diceCount)
{
if (diceCount >= _minDiceCount)
{
//too long. we've already found a shortest path.
//drop going deeper
return -1;
}
var currentSquare = path.Peek();
var diceCounts = new List<int>();
int newDiceCount;
var ignoreNormalJump = false;
for (var i = 0; i <= STEP_SIZE; i++)
{
var newSquare = currentSquare + i;
if (newSquare == TOP)
{
//got there
var totalDiceCount = diceCount + (i == 0 ? 0 : 1);
_minDiceCount = Math.Min(_minDiceCount, totalDiceCount); //register the shortest path
return totalDiceCount;
}
if (_jumps.All(j => j.Start != newSquare)) continue; //only process jumps
var jump = _jumps.First(j => j.Start == newSquare);
if (path.Contains(jump.End))
continue; //already been here
path.Push(jump.Start);
path.Push(jump.End);
newDiceCount = FindMinimumDice(path, diceCount + (i == 0 ? 0 : 1));
path.Pop();
path.Pop();
if (newDiceCount != -1)
diceCounts.Add(newDiceCount);
if (i == 0 && !OptionalJump) //the current squre is a jump that should be taken
{
ignoreNormalJump = true;
break;
}
}
if (!ignoreNormalJump)
{
var longestJump = 0;
for (var i = STEP_SIZE; i > 0; i--)
{
if (_jumps.All(j => j.Start != currentSquare + i))
{
longestJump = currentSquare + i;
break;
}
}
if (longestJump != 0)
{
path.Push(longestJump);
newDiceCount = FindMinimumDice(path, diceCount + 1);
path.Pop();
if (newDiceCount != -1)
diceCounts.Add(newDiceCount);
}
}
return !diceCounts.Any() ? -1 : diceCounts.Min();
}
}
class Program
{
static void Main(string[] args)
{
var sal = new SnakeAndLadder();
//set OptionalJump to true if the jump is optional
//sal.OptionalJump = true;
sal.AddJump(10,60);
sal.AddJump(51,100);
Console.WriteLine(sal.Solve());
Console.ReadLine();
}
}
}
答案 3 :(得分:0)
广度优先搜索(BFS)或动态编程解决方案将使用O(N)空间在O(N)时间内工作。
初始化:保留辅助阵列以保持梯子和蛇。假设从第x个到第y个单元格有一个梯子。所以auxi [x] = y。如果有从单元格x到y的蛇,x>y
则保留auxi[x]=-1
。如果当前单元格中没有梯形图或蛇形图,请保持auxi [x] = x;
动态编程解决方案:
res[top]=0;
for(int i = top-1; i>=0; i--) {
res[i] = INF;
for(int j=1; j<=6; j++){
if(i-j<0)break;
if(auxi[i+j]>-1) // if i+jth cell is start of a snake, we'll always skip it
res[i]=min( res[i] , res[auxi[i+j]]+1 );
}
}
我们总是跳过一个蛇开始的细胞,因为我们假设,在x的细胞上,蛇开始,它在第y个细胞上结束,在那里,y
答案 4 :(得分:0)
o(n)中C#中的解决方案。
构建一个帮助矩阵来检查每个步骤,看看到达那里的最小方法是什么,并添加一个。
const int BoardSize = 100;
const int MaxStep = 6;
static void Main()
{
// - means a ledder ending at the pos
// + means a snake (taking you back n steps)
int[] arr = new int[] {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 8, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -71, -1, -1 };
Console.WriteLine("Steps needed: " + solve(arr));
}
public static int solve(int[] inArr)
{
int[] arr = new int[BoardSize];
arr[0] = 1;
for (int i = 0; i < BoardSize; ++i)
{
// steps here is the minimum of all the positions in all the previos 6 cells +1
if (i < MaxStep)
arr[i] = 1;
else
{
int extraOption = int.MaxValue;
if (inArr[i] < -1 || inArr[i] > 0)
extraOption = arr[i + inArr[i]];
else if (inArr[i] > 0)
extraOption = arr[i + inArr[i]];
arr[i] = min(arr[i - 1], arr[i - 2], arr[i - 3], arr[i - 4], arr[i - 5], arr[i - 6], extraOption) + 1;
}
}
for (int i = 0; i < BoardSize; ++i)
{
Console.Write(arr[i] + "\t");
if ((i + 1) % 10 == 0)
Console.WriteLine("");
}
return arr[arr.Length-1];
}
public static int min(int a, int b, int c, int d, int e, int f, int g)
{
int ab = Math.Min(a,b);
int cd = Math.Min(c,d);
int ef = Math.Min(e,f);
return Math.Min(Math.Min(ab, cd), Math.Min(ef,g));
}
答案 5 :(得分:0)
这个程序可以模拟实际场景......如果符合预期,请告诉我。
import java.util.HashMap;
import java.util.Map;
public class SnakeLadder {
private Map<Integer,Integer> snakeLadderMapping=new HashMap<Integer,Integer>();
private int winPosition=100;
private int currentPosition=1;
public SnakeLadder(){
snakeLadderMapping.put(9, 19);
snakeLadderMapping.put(17, 5);
snakeLadderMapping.put(12, 40);
snakeLadderMapping.put(24, 60);
snakeLadderMapping.put(68, 89);
snakeLadderMapping.put(50, 12);
snakeLadderMapping.put(84, 98);
snakeLadderMapping.put(75, 24);
snakeLadderMapping.put(72, 16);
}
public int startGame(){
int count=0;
while(currentPosition!=winPosition){
count++;
getNextPosition(rollDice());
}
System.out.println("Game Won!!!!!!");
return count;
}
public int rollDice(){
return 1+ (int)(Math.random()*5);
}
public void getNextPosition(int diceValue){
int temp=currentPosition+diceValue;
if(snakeLadderMapping.containsKey(temp)){
currentPosition=snakeLadderMapping.get(temp);
}else{
if(temp<=winPosition){
currentPosition=temp;
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
SnakeLadder l=new SnakeLadder();
System.out.println("No of Steps to win:"+l.startGame());
}
}
答案 6 :(得分:0)
请在此处查看完整的代码解决方案 - https://algorithms.tutorialhorizon.com/snake-and-ladder-problem/
答案 7 :(得分:0)
此Snake and Ladder游戏代码使用 Python编程语言构建。
简单的代码就能赢得蛇梯游戏。
****************蛇和梯子游戏代码*************************
$ virtualenv -p python3 venv
$ source venv/bin/activate
(venv)$ pip install git+https://github.com/Supervisor/supervisor.git
(venv)$ pip freeze