取多次方的前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位数。
你可以假设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;
}
浙公网安备 33010602011771号