NUOJ 88

思路1:

找规律,本题若是直接暴力搜索,就是f(n)=2^n-1,然后f(n)%1000000,那么结果会越界;所以考虑用f(n+1)=(2*f(n)+1)%1000000,不过遇到较大数据的时候,会出现超时的情况,毕竟这个结果是线性时间增长的,和输入数据体量的大小有直接关系,所以这里还需要再次考虑优化。通过数据对比发现,当n>10005时,有f(123456)=f(23456)  f(123456789)=f(23456789)=...=f(56789)  即略去高位,剩下五位数。但是还需要考虑的是 if(m%100000<6),需要有m=100000+m%10;如此处理之后就不会超时了。

 1 #include <iostream> 
 2 using namespace std;
 3 
 4 int num[100006];
 5 int main(){
 6     int N,m,i;
 7     num[1]=1;
 8     for(int i=2;i<100006;i++){
 9         num[i] = (2*num[i-1]+1)%1000000;
10     }
11     cin>>N;
12     while(N--){
13         cin>>m;
14         if(m>100005){ 
15             if(m%100000<6 ){   
16                 m = 100000+m%10;    
17             }
18             else{
19                 m = m%100000;
20             }
21         }
22         cout<<num[m]<<endl;
23     }
24      
25 }

 思路2:

我们知道汉诺塔的公式是f(n)=2^n-1

而f(n)%1000000= (2^n-1)%1000000 = 2^n%100000-1 

而2^n%1000000可以用快速幂算法计算,代码如下:

 1 #include <iostream> 
 2 using namespace std;
 3 
 4 long long fastmod(long long a,long long b,long long c){
 5     long long num=1;
 6     a%=c;//这里不进行初始化也是可以的
 7     
 8     while(b>0){
 9         if(b%2==1){
10             num=(num*a)%c;    
11         }
12         b/=2;     //这一步将b->log2(b) 
13         a=(a*a)%c;  
14     }
15     return num;
16 }
17 
18 int main(){
19     int n;
20     cin>>n;
21     while(n--){
22         long long m;
23         cin>>m;
24         cout<<fastmod(2,m,1000000)-1<<endl;
25     }
26 }

 

posted on 2016-04-03 11:39  逸阳  阅读(243)  评论(0编辑  收藏  举报

导航