初识汉诺塔问题 – supervsky

汉诺塔

汉诺塔(Tower of 河内)是人印度的使闻名。,当梵天产量了泥土,它修建了三个金柱。,一柱从鉴于到顶部绒头有64个金盘。。梵定命令Brahman从上面重行名列前茅圆盘并把它放在许多石头上。。并任命,磁盘不克不及在小圆盘上缩小。,你但是在三个柱子当中一次庄严的一个人圆盘。。

——引自维基百科

若给汉诺塔使闻名中三根柱子使著名用英文字母a,b,C命名,采用,要不是一列积蓄N盘(1)。<=n<=100000), 若要把a柱子上的所有圆盘转移到c柱子上,问最少必要庄严的多少次圆盘。

庄严的压缩磁盘的任命列举如下:

  1. 一次但是庄严的一个人压缩磁盘。
  2. 大直径圆盘必然要放在小圆盘上。

反复求解

汉诺塔成绩经过复杂的反复停止求解,法典简约。,通俗易懂。事实上汉诺塔成绩的庄严的次数是有法则可寻的,经过反复法典找出确切的的任命。,并经过算学方式赢得奏效能力才是黄金时代的。

  • 当n=1时,一根柱子要不是一个人圆盘。,径直地庄严的到C列
  • 当n>1时,基本原则任命1和2,将列n-1磁盘移到B列。,那时将剩的磁盘庄严的到C。,那时将暂时积蓄在B上的N-1盘庄严的到C。

反复解事实上的是失效PR的攀登的褶皱。,何苦经过庄严的N-1盘O来反复前述的两点。。C法典的反复解如图3-1所示。。

void Hanoi(int n, char a, char b, char c)
{
    if(n == 1)
    {
        庄严的(A), c);
    }
    else
    {
        河内(N)-1, a, c, b); /*将列n-1磁盘移到B列。*/
        庄严的(A), c);      将剩的磁盘庄严的到C。
        河内(N)-1, b, a, c); 那时将暂时积蓄在B上的N-1盘庄严的到C。
    }
}

void Move(char a, char b)
{
    printf("Move 1 disk: %c ---------> %c\n", a, b);
}

图3-1    汉诺塔反复求解法典

如图3-1的法典可以从数据中演绎汉诺塔庄严的圆盘次数的递推相干:

  • 河内(N)) = 1 , n =1 ;
  • 河内(N)) = 2 * 河内(N)-1) + 1, n>1;

令b(n) = 河内(N))+1,可以从数据中演绎后记,B(n)是鉴于2。,几多比2。这么样就可以赢得,

b(n) = 2n, n>0

河内(N)) = 2n – 1, n>0


补充约束合格证书的汉诺塔

Q: 假如添加限度局限合格证书,磁盘但是在邻近列当中庄严的。,以什么方式处置?假定A, b, 并排C,当中的B,即a, C不邻近,在A到C上庄严的磁盘必然要率先庄严的到B。,那时搬到C.。

From TOJ 3270 Strange Hanoi Tower

相同的的处置方案经过反复求解。,基本原则怪人任命和新的约束合格证书,导出了活动圆盘数的法则。。

  • 当n=1时,一根柱子要不是一个人圆盘。,搬到B先,再次庄严的到C
  • 当n>1时,率先,A列的N-1盘经过B列庄严的到C。,那时将剩的压缩磁盘庄严的到B。 那时将C列N-1盘经过B列庄严的到A。 那时将B列的流行的不料磁盘庄严的到C。,末版,列的N-1盘经过B庄严的到C。

反复法典如图3-2所示。。

void Hanoi(int n, char a, char b, char c)
{
    if(n==1)
    {              //一根柱子要不是一个人圆盘。,搬到B先,再次庄严的到C
        庄严的(A), b);
        庄严的(B), c);
    }
    else
    {
        河内(N)-1, a, b, c); //率先,A列的N-1盘经过B列庄严的到C。
        庄严的(A), b);          A列的下剩磁盘庄严的到B
        河内(N)-1, c, b, a) 将C列N-1盘经过B列庄严的到A。
        庄严的(B), c);          将B列的流行的不料磁盘移到C。
        河内(N)-1, a, b ,c); 列的N-1盘经过B庄严的到C。
    }
}
void Move(char a, char b)
{
        printf("%c --> %c\n", a, b);
}

 图3-2    补充约束合格证书的汉诺塔反复法典

可以从图3-2中赢得。,静态圆盘数与DIS数当中的递推相干,

  • 当n=1时,河内(N)) = 2;
  • 当n>1时,河内(N)) = 3 * 河内(N)-1) + 2;

总算赢得:

河内(N)) = 3n – 1, n>0

因此话题的奏效能够罕有的大。,出口奏效应该是 防卫1,000,000,007。

高阶必须的幂模

因而toJ 3270因此科目被翻译成(3)n – 1) % 1000000007道算学题。对高阶必须的幂模运算,它可以经过消电处置。。船驶往的法典如图3-3所示。。

#include 
constlonglong p = 1000000007;

longlong power(longlong x, longlong n)
{//
    if( n == 0)
        return1;
    elseif(n == 1)
        return x;
    else
    {
        longlong tmp = 功率(X), n/2);
        if( n % 2 == 1)
            return tmp * tmp * x % p;  // 若 n 为奇,3n = 3 * 3n/2 * 3n/2elsereturn tmp * tmp % p;      // 若 n 为偶,3n = 3n/2 * 3n/2    }
}

int main()
{
    longlong n;
    while(斯坎夫"%lld", &n) && n)
    {
        printf("%lld\n", power(3, n)-1);
    }
    return0;
}

图3-3    TOJ 3270 Strange Hanoi 塔式参照码

考虑:为什么必要采用这些办法?

在什么几多级数中,什么素数都可以缩减1。,因此工程的例子是1减去素数的一个人并发症。。

—— 费马

有兴趣的讲师可以里德手腕费马定理。。

发表评论

电子邮件地址不会被公开。 必填项已用*标注