链接:http://acm.hdu.edu.cn/diy/contest_showproblem.php?cid=16820&pid=1002
K次方
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 25 Accepted Submission(s) : 12
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
Author
shenlizhong
思路:这是一题典型的大数相乘的形式,直接套用函数公式肯定不行,题目要求输出前三位后三位,对于此有两步处理法
1·后三位,快速幂就可解决
2·前三位从100开始吧,一一枚举直达达到所求值为止,这里有个技巧,t所得结果的总为位数设h=100,一直进行h++,知道log(h*1.0<=(k*log(n*1.0)-(t-3)log(10.0))),为止,最终,将h--即可,(因为前面的循环多算了一个)
看代码:(参考了一下标程)
#include<stdio.h>
#include<math.h>
int pow_mod(int a,int b,int m)
{
if(b==0)
return 1;
int x=pow_mod(a,b/2,m);
__int64 ans=(__int64)x*x%m;
if(b%2==1)
ans=ans*a%m;
return (int)ans;
}
int main()
{
int n,k;
int a,b,t,h,i,j;
while(scanf("%d",&n)!=EOF)
{
while(n--)
{
scanf("%d%d",&a,&b);
k=(int)(b*log10(a*1.0)+1);//求位数
t=pow_mod(a%1000,b,1000);
for(h=100;log(h*1.0)<=b*log(a*1.0)-(k-3)*log(10*1.0);h++);//以对数的形式求得前三位的数值!!!!!!(绝!!!!)
h--;
printf("%3d...%03d\n",h,t);
}
}
return 0;
}