取多次方的前n位

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

3
123456 1
123456 2
2100000056 67333

Sample Output

123...456
152...936
982...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;
}    

 

 
 
     
 
 

posted on 2012-08-24 22:51  yumao  阅读(201)  评论(0)    收藏  举报

导航