取多次方的前n位

来源:互联网 发布:阿沁淘宝店叫什么 编辑:程序博客网 时间:2024/04/30 02:37

K次方

Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 23 Accepted Submission(s) : 10

Font: Times New Roman | Verdana | Georgia

Font Size:

Problem Description

所有在程式设计已经有点经验的人都知道,当k很大时你无法完整的表达出n k。例如: C语言的函数 pow(123456,455)能够用double资料型态来表达,但是你却无法得到所有正确的数字。然而,若是能知道一些最左边(leading)和最右边(trailing)数字的话,也可稍微得到一些满足。

Input

输入的第一行有一个整数T(T < 1001),代表有几组测试资料。接下来的T行,每行有2个正整数n和k。n可以用32位元的整数表达,而k<10000001。

Output

每组测试资料输出一行,输出LLL...TTT的样式。其中LLL代表n k的最左边3个数字,TTT代表n k的最右边3个数字。例如123456 2 = 15241383936,所以你应该输出152...936。
你可以假设n k至少有6位数。

Sample Input

3123456 1123456 22100000056 67333

Sample Output

123...456152...936982...016



由于m,也就是指数非常大,所以直接求肯定会爆,也就是说,要运用数学方法。

主要是要清楚怎样取结果的前n位;
 
方法:
 
      log(m^n)=n*logm
 
      m^n=a*10^b
 
      n*logm=loga+b*log10
 
      n*logm-b=loga
 
      b=int(n*logm)
 
      loga为n*logm的小数部分
 
      a=pow(10,loga)
 
      a在1~10之间
 
      a=a*100
 
      所以a即为m^n的前3位。
 
     另外,要注意的是,求后3位时,需要用二分法来节省时间。
 
代码实现:
 
#include<iostream>#include<math.h>using namespace std;int fen(int x,int pre){    if(x==1)        return pre;    int re=1;    if(x%2!=0)        re*=pre;    x=x/2;    int re1=fen(x,pre);    re*=re1*re1;    re%=1000;    return re;}int main(){    double n;    int m;    int n1;    cin>>n1;    while(n1--){           cin>>n>>m;           int c=n;           c=c%1000;           int flag=0;            int c1=fen(m,c);           double sum=m*log10(n);           int sum1=m*log10(n);           sum=sum-sum1;           double res1=pow(10,sum);           res1*=100;           int res=res1;           res=res%1000;           if(c1<10)              cout<<res<<"..."<<"00"<<c1<<endl;           else if(c1<100)              cout<<res<<"..."<<"0"<<c1<<endl;           else              cout<<res<<"..."<<c1<<endl;              }   return 0;}