zoukankan      html  css  js  c++  java
  • P1096 Hanoi双塔问题

    题目描述

    给定 A 、 B 、 C 三根足够长的细柱,在 A 柱上放有 2n 个中间有孔的圆盘,共有 n 个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为 n=3 的情形)。

    现要将这些圆盘移到 C 柱上,在移动过程中可放在 B 柱上暂存。要求:

    (1)每次只能移动一个圆盘;

    (2) A 、 B 、 C 三根细柱上的圆盘都要保持上小下大的顺序;

    任务:设 An 为 2n 个圆盘完成上述任务所需的最少移动次数,对于输入的 n ,输出 An 。

    输入输出格式

    输入格式:

     

    一个正整数 n ,表示在 柱上放有 2n 个圆盘。

     

    输出格式:

     

    一个正整数, 为完成上述任务所需的最少移动次数 An 。

    输入输出样例

    输入样例#1: 复制
    【输入样例1】
    1
    【输入样例2】
    2
    输出样例#1: 复制
    【输出样例1】
    2
    【输出样例2】
    6

    说明

    【限制】

    对于 50% 的数据, 1n25

    对于 100% 的数据,1n200

    【提示】

    设法建立 An 与An1 的递推关系式。

    漫威系列二:

    纯数学题,找规律。

    比较懒,一开始,,感觉模拟那个过程太复杂了,

    于是拿来了标程,从一到七跑了一遍。

    是这样的:

    清晰明了,看能不能找到规律。

    规律来了,就是这样!:

    ans答案一开始置为2,( 也就是 n ==1 时,ans = 2 )

    n依次变大的话,就每次增加 2,厉不厉害!!!

    然后就能直接写了。

     根据规律直接写出来的代码应该是这样的:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 using namespace std;
     7 
     8 int n;
     9 long long m;
    10 
    11 long long poww(int x,int y)
    12 {
    13     long long s=1;
    14     for(int i=1;i<=y;++i)
    15         s*=x;
    16     return s;
    17 }
    18 
    19 int main()
    20 {
    21     scanf("%d",&n);
    22     for(int i=1;i<=n;++i)    
    23         m+=poww(2,i);    
    24     printf("%lld",m);
    25  } 

     哦,可惜因为精度范围问题拿不了满分。

    比如一个样例数据:

    input:

    90

    output: 

    2475880078570760549798248446

    所以上面那个代码是不会输出这么大一个数的。

    它会输出一个负数。

    这时候就需要高精度了。

    感觉无非就是将很大的数分离数位来记录。。

    生产于本校的某大佬的正解思路是这样的:

    原文:

    先找出An的通项公式,而两个相同的圆盘移动方法和一个圆盘的移动方法差不多,

    只要最后再乘二就好了,先考虑每种大小一个圆盘

    而显然An=2*An-1+1,就相当于先把上面n-1个圆盘先挪走,再挪最大的,再把n-1个挪到它上面

    又因为A1=1,因此有An=2^n-1,最后再乘二,An=2^(n+1)-2

    写的话用高精度,算出2^(n+1),注意到2的幂的个位数字是2,4,8,6,所有再减二的时候不用考虑退位

     所以ac代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int a[205];
    int n,len,newl;
    
    int main()
    {
        scanf("%d",&n);
        a[1]=2;
        len=1;
        for(int j=1; j<=n; j++)
        {
            if(a[len]>=5)   
                newl=len+1;
            else newl=len;
            for(int i=len; i>=1; i--)
            {
                a[i]=2*a[i];
                if(a[i]>=10)
                {
                    a[i+1]=a[i+1]+1;
                    a[i]=a[i]-10;
                }
            }
            len=newl;
        }
        a[1]=a[1]-2;
        for(int i=len; i>=1; i--)    
            printf("%d",a[i]);
        return 0;
    }

     感兴趣的,大佬blog如下:

    http://www.cnblogs.com/cangT-Tlan/p/8044788.html

  • 相关阅读:
    第一天课程总结与心得体会
    面对一切新的事物。
    libgdx学习记录3——动画Animation
    Eclipse编辑器设置
    libgdx学习记录2——文字显示BitmapFont
    libgdx自制简易Flappy Bird
    libgdx学习记录1——图片显示Texture
    libgdx自制简易版Don't Touch The White Tile
    eclipse 最最最常用快捷键
    libgdx退出对话框
  • 原文地址:https://www.cnblogs.com/Mary-Sue/p/9132260.html
Copyright © 2011-2022 走看看