题意明确,让计算出起始有m个金片的汉诺塔金片全部移动到另外一个针上时需要移动的最少步数是多少?(由于结果太大,现在只要求算出结果的十进制位最后六位)
解题思路:大家都很熟悉汉诺塔求移动次数公式为f(n+1)=f(n)*2+1; 由于0<m<1000000000,按要求,只需要输出结果的十进制最后六位,即f(n+1)=(f(n)*2+1)%1000000(注意是1后面是6个0,刚开始我就弄错了)。由于m 取值范围太大,如果按公式计算一定会超时。经过测试多组数据发现,当m>100005时,有如下规律:f(123456)=f(23456); f(123456789)=f(23456789)(老实说,这规律确实不好找),即略去最高位。但还要注意一点,当 m%100000<6 时,则 m=100000+m%10。(这道题让我纠结了好长时间)
代码如下:
View Code
1 #include<iostream>
2 using namespace std;
3 #define Max 100006
4 int an[Max];
5 int main()
6 {
7 int n,i,m;
8 an[1]=1;
9 for(i=2;i<Max;i++)
10 an[i]=(an[i-1]*2+1)%1000000;
11 cin>>n;
12 while(n--)
13 {
14 cin>>m;
15 if(m>100005)
16 {
17 if(m%100000<6) m=100000+m%10;
18 else m%=100000;
19 }
20 cout<<an[m]<<endl;
21 }
22 return 0;
23 }
2 using namespace std;
3 #define Max 100006
4 int an[Max];
5 int main()
6 {
7 int n,i,m;
8 an[1]=1;
9 for(i=2;i<Max;i++)
10 an[i]=(an[i-1]*2+1)%1000000;
11 cin>>n;
12 while(n--)
13 {
14 cin>>m;
15 if(m>100005)
16 {
17 if(m%100000<6) m=100000+m%10;
18 else m%=100000;
19 }
20 cout<<an[m]<<endl;
21 }
22 return 0;
23 }