a的b次方的前N位数和后N位数

a^b,假如a和b分别是10000000 10000000,我们知道计算机是无法存储这样大的数的。

看来直接计算,然后取前N位和后N位,是不可能的了。

先来看后N位如何计算,假设N==3。

那么不管a实际上有多大,我们的计算结果实际上只和a的后3位有关,也就是说第四位开始对我们的答案是没有影响的,能理解么?

所以我们先让a对1000取模,然后利用快速幂算法求出a^b次方,过程中别忘记了对1000取模。

 

再来看前N位如何计算,同样假设N==3.

假设a^b==c。那么我们对c取一个log10,得到d。

d肯定是一个浮点数,我们先看d的整数部分,10^(d的整数部分)等于100000....(d个0),好了,注意观察,第一个数是1,其他都是0。

也就说,10^(d的小数部分)最终将直接影响最左边的N位数。将这个结果乘以1,就是前1位的答案,乘以10,就是前2位的答案。。。类推

 

可以拿HDU 1060和1061练练手

 

View Code
 1 #include<iostream>
 2 #include<cmath>
 3 using namespace std;
 4 
 5 int pow(int a,int k) //后3位数的快速幂算法
 6 {
 7     int ans=1;
 8     a%=1000;
 9     while(k)
10     {
11         if(k&1)
12         {
13             ans=ans*a;
14             ans%=1000;
15         }
16         a=a*a;
17         a%=1000;
18         k>>=1;
19     }
20     return ans;
21 }
22 
23 int main()
24 {
25     __int64 c;
26     double a,b;
27     int n,m;
28     int cas;
29     scanf("%d",&cas);
30     while(cas--)
31     {
32         scanf("%d%d",&n,&m);
33         a=m*log10(0.0+n);
34         c=(__int64)a; //整数部分
35         b=a-c; //小数部分
36         c=(__int64)(pow(10.0,b)*100); //结果乘以100,也就意味着是前3位
37         printf("%I64d...%03d\n",c,pow(n,m));
38     }
39     return 0;
40 }

 

 

posted @ 2012-10-09 13:03  Accept  阅读(1506)  评论(0编辑  收藏  举报