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  }

 

 

你可能感兴趣的:(OJ)