nyoj 88 汉诺塔(一)
汉诺塔(一)
时间限制:1000 ms | 内存限制:65535 KB
难度:3
- 描述
-
在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
现在请你计算出起始有m个金片的汉诺塔金片全部移动到另外一个针上时需要移动的最少步数是多少?(由于结果太大,现在只要求你算出结果的十进制位最后六位)
- 输入
- 第一行是一个整数N表示测试数据的组数(0<N<20)
每组测试数据的第一行是一个整数m,表示起始时金片的个数。(0<m<1000000000) - 输出
- 输出把金片起始针上全部移动到另外一个针上需要移动的最少步数的十进制表示的最后六位。
- 样例输入
-
2 1 1000
- 样例输出
-
1 69375
- 来源
- [张云聪]原创
- 上传者
- 张云聪
- 开始以为直接模拟会超时 发现是log(n)的时间 不会超时
- 因为数据量不是很大
- 找到循环节点 12500 但是 要到12506 才是为 a【6】 但是一直wa 真的有点小郁闷
-
View Code
1 2 #include <iostream> 3 #include <cstdio> 4 typedef long long LL; 5 using namespace std; 6 const int N=12506; 7 int m=1000000; 8 LL work(LL i) 9 { 10 LL p=i,t=2; 11 LL ans=1; 12 while(p) 13 { 14 if(p&1) ans=(ans%m)*(t%m)%m; 15 t=(t%m)*(t%m)%m; 16 p>>=1; 17 } 18 return --ans; 19 } 20 21 int main() 22 { 23 24 int T; 25 scanf("%d",&T); 26 while(T--) 27 { 28 LL n; 29 scanf("%lld",&n); 30 LL sum=work(n); 31 printf("%lld\n",sum); 32 } 33 return 0; 34 } 35