解决此分布珠难题的算法? [英] Algorithm for solving this distributing beads puzzle?

查看:88
本文介绍了解决此分布珠难题的算法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个带有 N 个斑点的圆圈(如下所示),并且您在插槽中分布了 N 个珠子。



这里是一个例子:



每个珠子可以顺时针移动 X 个广告位,费用为 X ^ 2 美元。您的目标是在每个插槽中放置一个珠子。您必须花费最少的钱才能完成这项任务?



此问题的更有趣的变化:分配珠子拼图的算法(2)?

解决方案

在这个答案中,我假设珠子只能移动一次。否则,很明显珠子一次只能移动一个方块,这使这个问题变得不那么有趣了:方块的总和将降级为简单的移动之和。



问题可以在 O(n)时间内解决,在第4点,我给出了JavaScript实现。如果您想跳过导致该算法的推理,只需滚动至该部分。



编辑:我添加了一个部分 B ,其中分析了该问题的变体。



但是以下是导致所提出问题的建议算法的观察结果:



1。没有超车



应该注意的是,在最佳解决方案中,珠子永远不会移动,从而一个珠子超车另一个珠子。这两个小珠将
交换其目标位置的替代解决方案将总是产生较小的平方和。



为了使这一点正式化,我们说一个小珠从插槽编号 a 移至 b ,另一个从 c 移至 d 。要求它们不能逆时针移动。现在,假设第一个超越另一个,那么我们就有了所有这些真理:

  1。 < b 
2. c< d
3. a< c
4. b> d

然后,超车版本的移动平方和替代版本的移动平方(其中的小珠交换目标),像这样比较:

 (ba)²+(dc)²> (da)²+(bc)²

证明上述不平等可分解为:

 b²-2ab+a²+d²-2cd+c²> d²-2ad+a²+b²-2bc+c²
-2ab + -2cd> -2ad + -2bc
ab + cd< ad + bc
a(b-d)< c(b-d)
a< c

因此,在开始时共享相同插槽的珠子将总是以最佳解决方案出现在相邻的插槽中。



更普遍的是:



2。只看珠子保持相同顺序的解决方案



所以-如果我们对从同一位置开始的珠子给出(任意)命令,我们可以说

这也意味着我们可以很容易地找到一个最佳解决方案,其中珠子的顺序与原始输入相同(因为不包括超车)。找到一个候选解决方案,在该解决方案中,我们按订单号捡起珠子,然后将它们以相同的订货号放入插槽。这可能不是最佳解决方案,但可能是。如果它包含逆时针移动,甚至可能无效。



3。将解决方案循环到最佳状态



只需将所有磁珠移至下一个插槽,即可找到保持相同顺序的其他潜在解决方案,直到找到有效且最佳的解决方案为止。我将这样的移动称为一个循环。



如果第一个候选解决方案由于逆时针移动而无效,则可以直接找到最佳解决方案:最大的逆时针移动,并将此移动的相反方向添加到所有移动中,包括该移动。这将使所有违规移动均非逆时针方向(至少一个为零移动)。进一步循环显然会使平方和更大。因此,这是最佳解决方案。



如果另一方面,候选解决方案有效,但没有任何珠子保持原位,则可以通过循环使用反之亦然,即通过减小移动幅度,直到至少一个珠子保持位置。



4。算法



结合以上所有信息,我在这里介绍了用JavaScript实现的算法,可以在此实时代码段中对其进行测试:



  function bestSpread(beadCounts){//初始化var n = beadCounts.length; var solution = {//跟踪移动的平方和// //移动是多个插槽,并且只能是正数(顺时针)。 sumSquares:0,//跟踪移动总和。 sumMoves:0,//每个插槽,每个珠子保留一个元素,但是//我们从空数组开始。movePerSlotPerBead:[],}; //建立第一个非优化的解决方案。 //按FIFO顺序将小珠分配给连续的插槽。 // * move *,当添加到当前插槽号时,标识//在此解决方案中需要结束珠的第一个插槽。请注意,此初始解决方案//可能会逆时针移动。稍后将予以纠正。 // = O(n)var move = 0,totalBeadCount = 0,minMove = 0; beadCounts.forEach(function(beadCount,slotId){//检查总和totalBeadCount + = beadCount; //查看下一个bead将被移动到的位置(相对于插槽)move + = beadCount-1; //并保持最小值。可以为负数,表示//逆时针移动。如果(move< minMove) //如果小珠数不等于插槽数,则中止,如果(totalBeadCount!== n)返回{error: invalid input}; //确保没有逆时针移动,并且至少一个小珠保持不动(0),从而改善解决方案。 //应用从上一循环获得的校正以确保这一点。 // = O(n)move = -minMove; beadCounts.forEach(function(beadCount,slotId){solution.movesPerSlotPerBead [slotId] = []; //将每个磁珠移至(; beadCount> 0; beadCount--,move ++)的下一个可用插槽中{//存储移动对于这个珠子,solution.movesPerSlotPerBead [slotId] .push(move); solution.sumMoves + = move; solution.sumSquares + = move * move;} //补偿slotId move的增量move--;}); //现在解决方案是最佳的://逆时针骑车将使至少一个小珠沿着该方向运动; // //顺时针循环会增加平方和(因为所有移动都是//非负值)返回解;} function randomInput(n){//从所有零珠子的插槽开始:beadCounts = Array.from({length :n},x => 0); //将小珠随机分配给各个插槽,并为(var i = 0; i< n; i ++)保持每个插槽的计数。{beadCounts [Math.floor(Math.random()* n)] ++; } return beadCounts;} //与I / Ovar链接input = document.getElementById('input'); var randomize = document.getElementById('randomize'); var compute = document.getElementById('calculate'); var output = document.getElementById('output'); //捕获事件randomize.onclick = function(){var n = 5 + Math.floor(Math.random()* 20); input.value = randomInput(n).join(’,’); compute.onclick();}; calculate.onclick = function(){var beadCounts = input.value.split(’,’)。map(Number); var solution = optimumSpread(beadCounts); if(solution.error){output.textContent =‘错误:’+ solution.error;返回; } output.textContent ='\nInput:'+ JSON.stringify(beadCounts)+'\n移动平方和:'+ solution.sumSquares +'\n移动总和:'+ solution.sumMoves +'\ nMoves [slot] [bead]:'+ JSON.stringify(solution.movesPerSlotPerBead);};  

 以逗号分隔的每个插槽的珠子数量列表:< br /><输入id =输入 size = 40 value = 3,0,1,0, 1,0,2,2,2,1,1,0,1,0''>< button id = randomize> Randomize< / button>< br />< button id = calculate >查找最佳点差< / button>< / br>< pre id = output>< / pre>  

div>



此代码段采用一个数组,其中每个索引表示一个插槽,该值表示该插槽中的珠子数量。它输出原始数组,可选解的平方和以及珠子的移动列表。



问题中示例问题的输出为:

 输入:[3,0,1,0,1,0,2,2,2,2 ,1,1,0,1,0] 
移动的平方和:60
移动的总数:26
移动[slot] [bead]:[[1,2,3 ],[],[2],[],[1],[],[0,1],[1,2],[2,3],[3],[3],[],[2 ],[]]

因此示例配置的答案是:60美元。






B。附录:没有顺时针要求



如果取消了顺时针移动的要求,并且移动方向可能会怎样?并没有要求,但是我认为这是一个有趣的变体。



以下是适用于该情况的其他观察结果:



B.1。一个解决方案的平方和可以用于下一个



为了找到该新配置的平方和,并不需要实际执行一个循环:



假设我们有三个小珠和三个槽,并且通过将它们分别移动到 x,y z 个插槽。例如,如果它们都在插槽0中,则我们可以得到 x,y,z 值分别为0、1、2(如果为-1、0、1甚至5、6、7,



平方和为:

 x²+y²+z²

如果现在我们循环使用此解决方案,从而在每个磁珠的上方添加一个插槽移动,则正方形变为:

 (x + 1)²+(y + 1)²+(z + 1)² 

或:

 x²+y²+z²+3 +2(x + y + z)

通常,使用n个珠子循环配置会增加以下项的平方和:

  n + 2.sum(移动)

因此,算法可以利用该优势并快速计算解决方案的平方和循环产生的结果。可以为后续循环重复此操作。



B.2。最后,每个连续周期(解决方案)的平方和将是具有抛物线形状的函数,即一次是局部的平方和。



已找到最小数量,因此无需寻找另一个;没有。从上面的公式可以看出, sum(moves)的值增加了。最多两个相邻循环的平方和相等。



B.3。算法



此处遵循在JavaScript中实现的算法:



  function bestSpread(beadCounts) {//初始化var n = beadCounts.length; var solution = {//跟踪移动的平方和// //移动是多个插槽,可以是负数也可以是正数。 sumSquares:0,//跟踪移动总和。 sumMoves:0,//每个插槽,每个珠子保留一个元素,但是//我们从空数组开始。movePerSlotPerBead:[],}; //建立第一个非优化的解决方案。 //按FIFO顺序将小珠分配给连续的插槽。 // * move *,当添加到当前插槽号时,标识//在此解决方案中需要结束珠的第一个插槽。 // = O(n)var move = 0,totalBeadCount = 0; beadCounts.forEach(function(beadCount,slotId){solution.movesPerSlotPerBead [slotId] = []; //检查总和totalBeadCount + = beadCount; //将每个磁珠移至(; beadCount> 0; beadCount-- ,move ++){//存储此磁珠的移动solution.movesPerSlotPerBead [slotId] .push(move); solution.sumMoves + = move; solution.sumSquares + = move * move;} //补偿slotId move- -;}); //如果小珠数不等于插槽数,则中止,如果(totalBeadCount!== n)返回{error: invalid input}; //查看是否可以通过在一个方向上移动所有珠子来改善解决方案。 // = O(n)bestMoveCorrection = 0; while(true){//仅可以在sumMoves moveCorrection =(solution.sumMoves< 0?1:-1)指示的方向上进行改进; //计算得出sumSquares的增量://(a + 1)²+(b + 1)²+ ... +(x + 1)²=a²+b²+ ... +x²+ n +2 (a + b + ... + x)sumSquaresChange = n + moveCorrection * 2 * solution.sumMoves; //如果(sumSquaresChange> = 0)中断,如果不再带来任何改善,则停止; //这是一个改进; sumMoves + = moveCorrection * n; solution.sumSquares + = sumSquaresChange; bestMoveCorrection + = moveCorrection; } //对解决方案应用校正,以使其最佳化// = O(n)solution.movesPerSlotPerBead.forEach(function(moves){move.forEach(function(move,idx){move [idx] + = bestMoveCorrection;} );}); return solution;} function randomInput(n){//从所有零珠子的插槽开始:beadCounts = Array.from({length:n},x => 0); //将小珠随机分配给各个插槽,并为(var i = 0; i< n; i ++)保持每个插槽的计数。{beadCounts [Math.floor(Math.random()* n)] ++; } return beadCounts;} //与I / Ovar链接input = document.getElementById('input'); var randomize = document.getElementById('randomize'); var compute = document.getElementById('calculate'); var output = document.getElementById('output'); //捕获事件randomize.onclick = function(){var n = 5 + Math.floor(Math.random()* 20); input.value = randomInput(n).join(’,’); compute.onclick();}; calculate.onclick = function(){var beadCounts = input.value.split(’,’)。map(Number); var solution = optimumSpread(beadCounts); if(solution.error){output.textContent =‘错误:’+ solution.error;返回; } output.textContent ='\nInput:'+ JSON.stringify(beadCounts)+'\n移动平方和:'+ solution.sumSquares +'\n移动总和:'+ solution.sumMoves +'\ nMoves [slot] [bead]:'+ JSON.stringify(solution.movesPerSlotPerBead);};  

 以逗号分隔的每个插槽的珠子数量列表:< br /><输入id =输入 size = 40 value = 3,0,1,0, 1,0,2,2,2,1,1,0,1,0''>< button id = randomize> Randomize< / button>< br />< button id = calculate >查找最佳点差< / button>< / br>< pre id = output>< / pre>  

div>



此代码段采用一个数组,其中每个索引表示一个插槽,该值表示该插槽中的珠子数量。它输出原始数组,可选解的平方和以及珠子的移动列表。



问题中示例问题的输出为:

 输入:[3,0,1,0,1,0,2,2,2,2 ,1,1,0,1,0] 
移动平方和:12
移动总和:-2
移动[slot] [bead]:[[-1,0 ,1],[],[0],[],[-1],[],[-2,-1],[-1,0],[0,1],[1],[1] ,[],[0],[]]

注意:这不是问题的答案,因为它允许逆时针移动。有关答案,请参阅此响应的前半部分。


Lets say you have a circle (like below) with N spots, and you have N beads distributed in the slots.

Here's an example:

Each bead can be moved clockwise for X slots, which costs X^2 dollars. Your goal is to end up with one bead in each slot. What is the minimum amount of money you have to spend to achieve this task?

More interesting variation of this problem: Algorithm for distributing beads puzzle (2)?

解决方案

In this answer I assume beads can only be moved once. Otherwise it would be evident that beads should only move one square at a time, which makes this problem much less interesting: the sum of squares would downgrade to a simple sum of moves.

The problem can be solved in O(n) time, and at point 4 I give a JavaScript implementation. If you want to skip the reasoning that lead to the algorithm, just scroll to that section.

Edit: I added a section B, where a variant of the problem is analysed.

But here are the observations that lead to the suggested algorithm for the question at hand:

1. No overtaking

It should be observed that in an optimal solution the beads will never be moved such that one bead "overtakes" another. The alternative solution where these two beads would swap their target slots would always give a lower sum of squares.

To formalise this a bit, let's say one bead moves from slot number a to b, and another from c to d. It is required that they cannot move counter-clockwise. Let's now assume the first overtakes the other, then we have all of these truths:

1. a < b
2. c < d
3. a < c
4. b > d

Then the squares of the moves of the overtaking version, and the squares of moves of the alternative version (where beads swap targets), compare like this:

(b-a)² + (d-c)² > (d-a)² + (b-c)²

Proof is that the above inequality breaks down to:

b²-2ab+a² + d²-2cd+c² > d²-2ad+a² + b²-2bc+c²
-2ab + -2cd > -2ad + -2bc
ab + cd < ad + bc
a(b-d) < c(b-d)
a < c
true

As a consequence, the beads that share the same slot at the start will always end up in neighbouring slots in the optimal solution.

More generally:

2. Only look at solutions where beads stay in same order

So -- if we give an (arbitrary) order to the beads that start in the same slot -- we can say that an optimal solution can be found where the order of beads is the same as in the original input (since overtaking is excluded).

This also means that we can quite easily find a candidate solution where we pick up the beads by order number and put them in the slot with that same order number. This might not be the optimal solution, but it could be. It might even be invalid if it contains a counter-clockwise move. But it is still useful to start with.

3. Cycle solution to optimal one

Any other potential solution that keeps the same order is found by just moving all beads to the next slot, until a valid and best solution is found. I will call such a move a cycle.

If the first candidate solution is invalid because of a counter-clockwise move, it is straightforward to find the best solution: take the largest counter-clockwise move, and add the opposite of this move to all the moves, including that one. This will make all offending moves non-counter-clockwise (at least one will be a zero-move). Cycling further will evidently make the sum of squares larger. So this is the optimal solution.

If on the other hand the candidate solution is valid, but none of the beads stays in position, the solution can be improved by cycling the other way round, i.e. by making the moves smaller, until at least one bead stays in position.

4. Algorithm

With all of the above information, I present here the algorithm implemented in JavaScript, which can be tested in this live snippet:

function optimalSpread(beadCounts) {
    // Initialisation
    var n = beadCounts.length;
    var solution = {
        // Keep track of sum of squares of moves
        // A move is a number of slots and only be positive (clockwise).
        sumSquares: 0,
        // Keep track of sum of moves.
        sumMoves: 0,
        // Per slot, keep an array with one element per bead, but
        // we start with empty arrays
        movesPerSlotPerBead: [],
    };
    // Build a first a non-optimised solution. 
    // Assign beads in FIFO order to consecutive slots.
    // *move*, when added to the current slot number, identifies the first slot where
    // a bead needs to end up in this solution. Note that this initial solution
    // may do counter-clockwise moves. This will be corrected later.
    // =O(n)
    var move = 0,
        totalBeadCount = 0,
        minMove = 0;
    beadCounts.forEach(function(beadCount, slotId) {
        // check sum
        totalBeadCount += beadCount;
        // See where the next bead would be moved (relative to slot)
        move += beadCount - 1;
        // and keep the minimum value. Can be negative, meaning a 
        // counter clockwise move.
        if (move < minMove) minMove = move;
    });
    // abort if number of beads is not equal to number of slots
    if (totalBeadCount !== n) return {error: "invalid input"}; 
    // Improve solution by making sure there are no counter-clockwise
    // moves, and at least one bead stays unmoved (0).
    // Apply correction we got from previous loop to ensure this.
    // =O(n)
    move = -minMove;
    beadCounts.forEach(function(beadCount, slotId) {
        solution.movesPerSlotPerBead[slotId] = [];
        // Move each bead into next available slot
        for (; beadCount > 0; beadCount--, move++) {
            // Store the move for this bead
            solution.movesPerSlotPerBead[slotId].push(move);
            solution.sumMoves += move;
            solution.sumSquares += move*move;
        }
        // Compensate the increment of slotId
        move--;
    });
    // The solution is now optimal:
    // Cycling counter-clockwise would make at least one bead go that way;
    // Cycling clockwise would increase the sum of squares (as all moves are
    //    non-negative values)
    return solution;
}

function randomInput(n) {
    // Start with slots having all zero beads:
    beadCounts = Array.from({length: n}, x => 0);
    // Randomly assign beads to slots, keeping a count per slot
    for (var i = 0; i < n; i++) {
        beadCounts[Math.floor(Math.random() * n)]++;
    }
    return beadCounts;
}

// Link with I/O
var input = document.getElementById('input');
var randomize = document.getElementById('randomize');
var calculate = document.getElementById('calculate');
var output = document.getElementById('output');

// Capture events
randomize.onclick = function() {
    var n = 5 + Math.floor(Math.random() * 20);
    input.value = randomInput(n).join(',');
    calculate.onclick();
};

calculate.onclick = function() {
    var beadCounts = input.value.split(',').map(Number);
    var solution = optimalSpread(beadCounts);
    if (solution.error) {
        output.textContent = 'Error: ' + solution.error;
        return;
    }
    output.textContent = 
        '\nInput: ' + JSON.stringify(beadCounts) +
        '\nSum of squares of moves: ' + solution.sumSquares +
        '\nSum of moves: ' + solution.sumMoves +
        '\nMoves[slot][bead]: ' + JSON.stringify(solution.movesPerSlotPerBead);
};

Comma-separated list of number of beads per slot:<br/>
<input id="input" size="40" value="3,0,1,0,1,0,2,2,2,1,1,0,1,0">
<button id="randomize">Randomize</button><br/>
<button id="calculate">Find optimal spread</button></br>
<pre id="output"></pre>

This snippet takes an array where each index represents a slot, and the value represents the number of beads in that slot. It outputs the original array, the sum of squares of the optional solution, and the list of moves for the beads.

Output for the example problem in the question is:

Input: [3,0,1,0,1,0,2,2,2,1,1,0,1,0]
Sum of squares of moves: 60
Sum of moves: 26
Moves[slot][bead]: [[1,2,3],[],[2],[],[1],[],[0,1],[1,2],[2,3],[3],[3],[],[2],[]]

So the answer to the example configuration is: 60 dollars.


B. Addendum: Without Clockwise Requirement

What if the requirement for clockwise moves were removed, and moves could be in any direction? This was not asked, but I thought it was an interesting variant.

Here are the additional observations that apply for that case:

B.1. Sum of squares of one solution can be used for next

A cycle does not need to be actually performed in order to find the sum of squares of that new configuration:

Let's say we have three beads and three slots, and the beads have each been moved to their target slots by moving them x, y and z slots respectively. For instance, if they all were in slot 0, we could get x, y, z values of 0, 1, 2 (but also -1, 0, 1 or even 5, 6, 7 if we want to exaggerate).

The sum of squares is:

x²+y²+z²

If now we cycle this solution and thus add one slot more to each bead's move, the squares become:

(x+1)²+(y+1)²+(z+1)²

or:

x²+y²+z²   +3    +2(x+y+z)

In general, cycling a configuration with n beads like that increases the sum of squares with this term:

n + 2.sum(moves)

So, the algorithm can take advantage of that and quickly calculate the sum of squares of the solution resulting from a cycle. This can be repeated for subsequent cycles.

B.2. Only one local minimum for sum of squares

Finally, the sum of squares for each consecutive cycle (solution), will be a function with a parabolic shape, i.e. once a local minimum has been found, there is no need to look for another one; there isn't. We can see that from the above formula for increasing values for sum(moves). At the most we might have an equal sum of squares for two neighbouring cycles.

B.3. Algorithm

Here follows the algorithm implemented in JavaScript:

function optimalSpread(beadCounts) {
    // Initialisation
    var n = beadCounts.length;
    var solution = {
        // Keep track of sum of squares of moves
        // A move is a number of slots and can be negative or positive.
        sumSquares: 0,
        // Keep track of sum of moves.
        sumMoves: 0,
        // Per slot, keep an array with one element per bead, but
        // we start with empty arrays
        movesPerSlotPerBead: [],
    };
    // Build a first a non-optimised solution. 
    // Assign beads in FIFO order to consecutive slots.
    // *move*, when added to the current slot number, identifies the first slot where
    // a bead needs to end up in this solution.
    // =O(n)
    var move = 0,
        totalBeadCount = 0;
    beadCounts.forEach(function(beadCount, slotId) {
        solution.movesPerSlotPerBead[slotId] = [];
        // check sum
        totalBeadCount += beadCount;
        // Move each bead into next available slot
        for (; beadCount > 0; beadCount--, move++) {
            // Store the move for this bead
            solution.movesPerSlotPerBead[slotId].push(move);
            solution.sumMoves += move;
            solution.sumSquares += move*move;
        }
        // Compensate the increment of slotId
        move--;
    });
    // abort if number of beads is not equal to number of slots
    if (totalBeadCount !== n) return {error: "invalid input"}; 
    // See if solution can be improved by shifting all beads in one direction.
    // =O(n)
    bestMoveCorrection = 0;
    while (true) {
        // Improvement is only possible in the direction dictated by sumMoves 
        moveCorrection = (solution.sumMoves < 0 ? 1 : -1);
        // Calculate the delta this brings to sumSquares:
        // (a+1)²+(b+1)²+ ... +(x+1)² = a²+b²+...+x² +n  +2(a+b+...+x) 
        sumSquaresChange = n + moveCorrection * 2 * solution.sumMoves;
        // Stop if this brings no improvement anymore
        if (sumSquaresChange >= 0) break;
        // It is an improvement; keep it
        solution.sumMoves += moveCorrection * n;
        solution.sumSquares += sumSquaresChange;
        bestMoveCorrection += moveCorrection;
    }
    // Apply correction to solution, to make it optimal
    // =O(n)
    solution.movesPerSlotPerBead.forEach(function(moves) {
        moves.forEach(function(move, idx) {
            moves[idx] += bestMoveCorrection;
        });
    });
    return solution;
}

function randomInput(n) {
    // Start with slots having all zero beads:
    beadCounts = Array.from({length: n}, x => 0);
    // Randomly assign beads to slots, keeping a count per slot
    for (var i = 0; i < n; i++) {
        beadCounts[Math.floor(Math.random() * n)]++;
    }
    return beadCounts;
}

// Link with I/O
var input = document.getElementById('input');
var randomize = document.getElementById('randomize');
var calculate = document.getElementById('calculate');
var output = document.getElementById('output');

// Capture events
randomize.onclick = function() {
    var n = 5 + Math.floor(Math.random() * 20);
    input.value = randomInput(n).join(',');
    calculate.onclick();
};

calculate.onclick = function() {
    var beadCounts = input.value.split(',').map(Number);
    var solution = optimalSpread(beadCounts);
    if (solution.error) {
        output.textContent = 'Error: ' + solution.error;
        return;
    }
    output.textContent = 
        '\nInput: ' + JSON.stringify(beadCounts) +
        '\nSum of squares of moves: ' + solution.sumSquares +
        '\nSum of moves: ' + solution.sumMoves +
        '\nMoves[slot][bead]: ' + JSON.stringify(solution.movesPerSlotPerBead);
};

Comma-separated list of number of beads per slot:<br/>
<input id="input" size="40" value="3,0,1,0,1,0,2,2,2,1,1,0,1,0">
<button id="randomize">Randomize</button><br/>
<button id="calculate">Find optimal spread</button></br>
<pre id="output"></pre>

This snippet takes an array where each index represents a slot, and the value represents the number of beads in that slot. It outputs the original array, the sum of squares of the optional solution, and the list of moves for the beads.

Output for the example problem in the question is:

Input: [3,0,1,0,1,0,2,2,2,1,1,0,1,0]  
Sum of squares of moves: 12  
Sum of moves: -2  
Moves[slot][bead]: [[-1,0,1],[],[0],[],[-1],[],[-2,-1],[-1,0],[0,1],[1],[1],[],[0],[]]

NB: This is not the answer to the question, because it allows counter-clockwise moves. For the answer, see first half of this response.

这篇关于解决此分布珠难题的算法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆