zoukankan      html  css  js  c++  java
  • 【9107】Hanoi双塔问题(NOIP2007)

    Time Limit: 10 second
    Memory Limit: 2 MB

    问题描述
    给定A,B,C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的。现要将这些圆盘移到C柱上,在移动过程中可放在B柱上暂存。要求: 
    (1)每次只能移动一个圆盘; 
    (2) A、B、C三根细柱上的圆盘都要保持上小下大的顺序;
    任务:设An为2n个圆盘完成上述任务所需的最少移动次数,对于输入的n,输出An。

    Input

    输入为一个正整数n,表示在A柱上放有2n个圆盘

    Output

    输出仅一行,包含一个正整数,为完成上述任务所需的最少移动次数An。(最后用换行结束)

    Sample Input

    1
    

    Sample Output

    2
    
    

    Sample Input2

    2
    

    Sample Output2

    6

    【题解】

    先不考虑有相同圆盘的情况。

    即n个不同的圆盘。

    则需要把n-1个圆盘从a->b,然后把a上剩余的一个圆盘从a->c。然后把b上的n-1个圆盘从b->c。

    这里的两步:把n-1个圆盘从a->c,和n-1个圆盘从b->c.所需要的步骤数。实际上就是把n-1个圆盘从a移动到c的步骤数*2,因为是等价的。从a->b和从b->c移动的圆盘个数都是一样的,这样。

    然后还要多一步就是把a上的一个圆盘放到c。

    所以得到递推式。(没有相同的圆盘。然后是n个不是2*n个的递推式)

    An表示把n个圆盘从a到c的步骤数。

    An=A(n-1)*2+1;

    然后玩一下数学游戏。

    An=A(n-1)*2+2-1;

    An+1=A(n-1)*2+2;

    An+1=2(A(n-1)+1)

    令Bn = (An+1);

    则Bn是一个等比数列。

    A1只有把1个圆盘从a移到c,步骤为1

    B1=A1+1 = 2;

    所以Bn=2^n

    然后An=2^n-1;

    现在考虑有重复圆盘的情况。

    其实只要乘上2就可以了。。

    比如n==1.

    A上有两个相同的圆盘。那就全都拿到C就好了。

    只不过要多移动一次了而已。

    然后每种圆盘都要多移动一次

    设Dn为2*n个圆盘(n种)要从a移动到c的步骤数。

    Dn=2*An=2^(n+1)-2;

    然后n可能很大。要用高精度。

    写一下高精度乘法即可。

    【代码】

    //2^(n+1)-2;
    #include <cstdio>
    
    int n, a[1000] = { 0 };//a数组用来存高精度的各个位上的数字。
    
    void input_data()
    {
    	scanf("%d", &n);
    }
    
    void get_ans()
    {
    	a[0] = 1;
    	a[1] = 1;//2^0 == 1;
    	for (int i = 1; i <= n + 1; i++) //然后乘上n+1个2.
    	{
    		int x = 0;
    		for (int j = 1; j <= a[0]; j++)//把每一位都乘上2.
    		{
    			a[j] = a[j] * 2 + x; //边乘边进位。
    			x = a[j] / 10;
    			a[j] = a[j] % 10;
    		}
    		while (x > 0) //可能要扩展位数。
    		{
    			a[0]++; 
    			a[a[0]] = x % 10;
    			x = x / 10;
    		}
    	}
    	a[1] -= 2;//直接减去2就好。不会出现要退位的情况。
    	//因为2的x次方除了2的0次方之外。其他的个位数字上的数字都大于等于2.这样。
    }
    
    void output_ans()
    {
    	for (int i = a[0]; i >= 1; i--) //倒序输出所有位上的数字。
    		printf("%d", a[i]);
    }
    
    int main()
    {
    	input_data();
    	get_ans();
    	output_ans();
    	return 0;
    }


  • 相关阅读:
    Runloop详解
    iOS高效裁剪图片圆角算法
    Runtime详解(下)
    Runtime详解(上)
    iOS UITextfield只允许输入数字和字母,长度限制
    iOS多线程(上)——GCD详解(上)
    @property、@sythesize以及Ivar和@dynamic讲解(下)
    iOS 循环引用讲解(中)
    @property详解,@property修饰符以及各个修饰符区别(上)
    PHP 使用 OSS 批量上传图片
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632310.html
Copyright © 2011-2022 走看看