您的位置:首页 > 其它

汉诺塔(一)

2015-08-31 20:03 190 查看

汉诺塔(一)

时间限制:1000 ms  |  内存限制:65535 KB难度:3描述在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。现在请你计算出起始有m个金片的汉诺塔金片全部移动到另外一个针上时需要移动的最少步数是多少?(由于结果太大,现在只要求你算出结果的十进制位最后六位)输入第一行是一个整数N表示测试数据的组数(0<N<20)每组测试数据的第一行是一个整数m,表示起始时金片的个数。(0<m<1000000000)输出输出把金片起始针上全部移动到另外一个针上需要移动的最少步数的十进制表示的最后六位。样例输入
2
1
1000
样例输出
1
69375
思路:
假设有n片,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。此后不难证明f(n)=2^n-1。与二进制有关且不能暴力,可以想到快速幂来求解。
AC代码:
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<string>using namespace std;typedef long long ll;#define T 1000000ll _pow(int n){ll res=1,k=2;while(n){if(n&1)res=(res*k)%T;n/=2;k=(k*k)%T;}return res;}int main(){/*freopen("input.txt","r",stdin);*/int n,m;scanf("%d",&n);while(n--){scanf("%d",&m);printf("%lld\n",_pow(m)-1);}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nyoj