NYOJ 88 汉诺塔(一)

地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=88

思路1:

对于汉诺塔求移动次数公式为f(n+1)=f(n)*2+1;
此题如果用要求十进制最后六位,f(n+1)=(f(n)*2+1)%100000;
每次输入层数,求出移动次数,但如果输入数据很大,利用此公式必定超时,经过多次测试,发现若输入数据大于100005,有如下规律,如:
f(123456)=f(23456); f(123456789)=f(23456789)---=f(56789)
即略去最高位,
但 if(m%100000<6)则需进行此操作 m=100000+m%10;
这样就不会超时了
 1 #include<stdio.h>
 2 int num[100006];
 3 int main()
 4 {
 5     int N,m,i;
 6     num[1]=1;  //只有一个的情况
 7     for(i=2;i<100006;i++)
 8        num[i]=(2*num[i-1]+1)%1000000;
 9     scanf("%d",&N);
10     while(N--)
11     {
12         scanf("%d",&m);
13         if(m>100005)
14         {
15             if(m%100000<6)
16                m=100000+m%10;
17             else
18                m%=100000;
19         }
20         printf("%d\n",num[m]);
21     }
22     return 0;
23 }

 

 
 
 
思路2:快速模幂法
 1  #include<iostream>
 2  #include<cmath>
 3  using namespace std;
 4  
 5  long long pow_mod(long long n)
 6  {
 7      if(n==1) return 2;
 8      long long t;
 9      t=pow_mod(n/2);
10      if(n%2==0)
11      {
12          return ((t%1000000)*(t%1000000))%1000000;
13      }
14      else
15      {
16          return (2*(t%1000000)*(t%1000000))%1000000;
17      }
18  }
19  
20  int main()
21  {
22      int test;
23      long long n;
24      cin>>test;
25      while(test--)
26      {
27          cin>>n;
28          cout<<pow_mod(n)-1<<endl;
29      }
30      return 0;
31  }

 

 

posted on 2012-08-14 15:07  mycapple  阅读(1040)  评论(0编辑  收藏  举报

导航