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 }