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

 

posted @ 2018-06-04 10:59  孟东行#  阅读(558)  评论(0编辑  收藏  举报