不要想那么复杂,先考虑3个元素移动2个位置,
123
231这里移动了3次,每个元素移动一次
312这里又是3次,共6次
#include <stdio.h>
int f(int n) // n是盘子数
{
if(1 == n)
{
return 1; //很容易得到 一个盘子当然只需要移动一次就得到结果
}
else
{
return f(n - 1)*2 + 1; // 简化版
//return f(n - 1) + 1 + f(n - 1);
// 这上面的式子的意思正如我上面所说 ,先将前n - 1 个盘子移动到过渡桩上面去,然后移动最后一个盘子,再移动前 n - 1 个盘子
// 所以是 f(n - 1) 的移动次数 加上最后一个盘子移动的一次 再加上f(n - 1)个盘子移动的次数 得到总次数
}
}
int main()
{
int n;
scanf("%d",&n); //盘子数
printf("%d个盘子总共移动次数为: %d",n,f(n));
return 0;
}
以上就是求解n个盘子需要移动的次数
而有时侯有的题目会考每次移动的盘子的步骤打印出来,那么就需要将上面的递归改变一下就可以得到每步的怎么移动的了
如下:
PS: 我就直接写递归函数了
void f(int n, char begin,char end,char through)
{
if(1 == n)
{
printf("%c -> %c\n",begin,end);
}
else
{
f(n - 1,begin,through,end); //移动前n - 1 个盘子到过渡盘
printf("%c -> %c\n",begin,end); // 将最后一个盘移动到最终柱子
f(n - 1,through,end,begin); // 将 n - 1 个盘子移动到最终柱子
}
}
如上就是每步盘子是如何移动的递归程序,只要明白了基本的移动方式,那么写出汉罗塔递归程序还是很好写的。
在解决数组循环左移问题时,计算答案为i × n而不是i × (n+1)的原因如下:
首先,我们需要明确数组循环左移的定义和目标。数组循环左移是指将数组中的元素依次向左移动k个位置,移动到数组末尾的元素再移到数组的开头,形成一个循环。
解法二通过一次循环将数组中的所有元素向左移动k个位置。其基本思路是,将数组分为两部分,前k个元素和剩下的n-k个元素。首先反转前k个元素,然后反转剩下的n-k个元素,最后对整个数组进行反转。这样可以实现循环左移。
在计算答案时,我们需要确定循环左移后每个元素的最终位置。假设循环左移k个位置,元素原来的位置为i,那么元素最终的位置为(i+k) % n,其中n为数组的长度。
这里的关键是要理解循环左移的含义。当元素的最终位置大于等于n时,需要将其重新映射到数组的开头,也就是取余操作(i+k) % n。这样才能保证整个数组形成一个循环。
因此,在解决数组循环左移问题时,计算答案为i × n而不是i × (n+1),是因为我们需要将元素的最终位置映射到数组的合法范围内,使用取余操作(i+k) % n即可实现这一目标。
希望这个解答能够帮助您理解为什么在解决数组循环左移问题时,计算答案为i × n而不是i × (n+1)。如果还有其他疑问,请随时提问。