如何找到具有过度环绕的数字的两个方向上的最短路径?

发布于 2025-01-01 04:32:53 字数 590 浏览 1 评论 0原文

假设我必须从 0 到 10 中选择一个数字。

我选择的数字是 6。

我要选择的下一个数字是 0。

现在的规则是我必须继续将数字递增 1 或递减 1,该数字也可以环绕最后一个数字。

现在最重要的是找到最短的方向。

所以

6-5-4-3-2-1-0 = 7 moves.
6-7-8-9-10-0 = 6 moves.

在这种情况下,增量获胜。

好吧,我想出了这段代码(可能被破坏了)

int movesInc = 1;
int movesDec = 1;
int curNumber = 6;
int nextNumber = 0;
while((curNumber-- % 11) != nextNumber)
    movesDec++;

while((curNumber++ % 11) != nextNumber)
    movesInc++;

现在而不是在两个方向上使用 while 循环.. 并找出哪个需要更少的移动..

有什么方法可以在没有 while 循环的情况下做到这一点?也许只是某种数学方程?

Let's say I have to pick a number from 0-10.

The number I pick is 6.

The next number I want to pick is 0.

Now the rules are I have to keep incrementing the number by 1 or decrementing it by 1, the number can also wrap around the last number.

Now whats most important is to find which direction is shortest to take.

So

6-5-4-3-2-1-0 = 7 moves.
6-7-8-9-10-0 = 6 moves.

So incrementing wins in this case.

Well I came up with this code (probably broken)

int movesInc = 1;
int movesDec = 1;
int curNumber = 6;
int nextNumber = 0;
while((curNumber-- % 11) != nextNumber)
    movesDec++;

while((curNumber++ % 11) != nextNumber)
    movesInc++;

Now instead of using a while loop in both directions.. and finding out which takes less moves..

any way to do this without a while loop? just maybe some kind of mathematical equation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

世界等同你 2025-01-08 04:32:53

您的代码实际上无法正常工作,原因有两个:

您应该以 11 为模而不是 10(我看到您现在已经根据我之前的评论修复了这个问题)。

Java 和 C++ 中的 % 运算符并不像您想象的那样处理符号。

这确实有效,尽管它不太漂亮,而且不需要循环。

它针对从 6 开始到 0 结束进行了测试,我预计它通常可以正常工作。对于不同的范围,您当然需要更改结果为负时添加的数字。

    int curNumber = 6;
    int nextNumber = 0;
    int movesInc = (nextNumber - curNumber) + 1
                    + ((nextNumber > curNumber)? 0: 11);
    int movesDec = (curNumber - nextNumber) + 1
                    + ((nextNumber < curNumber)? 0: 11);

这里的 + 1 是因为您正在计算两个端点。三元表达式处理 0 附近的情况。

Your code doesn't in fact work properly for two reasons:

You should be working modulo 11 instead of 10 (I see you've now fixed this per my earlier comment).

The % operator in Java and C++ doesn't deal with signs the way you think.

This does work, though it's not pretty, and it doesn't need loops.

It is tested for the start at 6 and end at 0, and I expect it works generally. For a different range, you'd of course need to change the number added when the result goes negative.

    int curNumber = 6;
    int nextNumber = 0;
    int movesInc = (nextNumber - curNumber) + 1
                    + ((nextNumber > curNumber)? 0: 11);
    int movesDec = (curNumber - nextNumber) + 1
                    + ((nextNumber < curNumber)? 0: 11);

The + 1 here is because you're counting both endpoints. The ternary expression is what handles going around 0.

掩于岁月 2025-01-08 04:32:53
int curNumber;
int nextNumber;
//calculate the modulo size by the highest number
int module = 10 + 1;
//calculate the direct distance to the nextNumber
int directDist = nextNumber - curNumber;

int nextNumberWrapped;
//calculate the wrapped distance, deciding the direction which wraps
if(directDist < 0)
    //wrapping in positive direction: 10 -> 0
    nextNumberWrapped = nextNumber + module;
else
    //wrapping in negative direction 0 -> 10
    nextNumberWrapped = nextNumber - module;
//calculating the wrapped distance
int wrappedDist = nextNumberWrapped - curNumber;
//assume the directDist to be shortest
int shortestDist = directDist;
//proof wrong if neccessary (compare the distances absolute values)
if(abs(wrappedDist) < abs(directDist))
   //save the signed distance
   shortestDist = wrappedDist;

ShortestDist 的绝对值告诉您最短距离的长度,而符号则告诉您方向。
因此,当符号为负时,您必须递减;当符号为正时,您必须递增以走最短的路。

http://ideone.com/0yCDw

另外,您的示例似乎是错误的。数字之间的每一个 - 都是一步,使您比您计算的少一步:

6-5-4-3-2-1-0
 ^ ^ ^ ^ ^ ^
 1 2 3 4 5 6  -> 6 moves
6-7-8-9-10-0
 ^ ^ ^ ^  ^ 
 1 2 3 4  5 -> 5 moves
int curNumber;
int nextNumber;
//calculate the modulo size by the highest number
int module = 10 + 1;
//calculate the direct distance to the nextNumber
int directDist = nextNumber - curNumber;

int nextNumberWrapped;
//calculate the wrapped distance, deciding the direction which wraps
if(directDist < 0)
    //wrapping in positive direction: 10 -> 0
    nextNumberWrapped = nextNumber + module;
else
    //wrapping in negative direction 0 -> 10
    nextNumberWrapped = nextNumber - module;
//calculating the wrapped distance
int wrappedDist = nextNumberWrapped - curNumber;
//assume the directDist to be shortest
int shortestDist = directDist;
//proof wrong if neccessary (compare the distances absolute values)
if(abs(wrappedDist) < abs(directDist))
   //save the signed distance
   shortestDist = wrappedDist;

The absolute value of shortestDist tells you the length of the shortest distance and the sign gives you the direction.
So when the sign is negative you have to decrement and when it is positive you must increment to go the shortest way.

http://ideone.com/0yCDw

Also your example seems wrong. Each - between the numbers is one step, leaving you with one step less than you counted:

6-5-4-3-2-1-0
 ^ ^ ^ ^ ^ ^
 1 2 3 4 5 6  -> 6 moves
6-7-8-9-10-0
 ^ ^ ^ ^  ^ 
 1 2 3 4  5 -> 5 moves
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文