Leading and Trailing
题面
题意
输出 nk的前3位数与后3位数,如果位数不够补0。
分析
nk的后三位,相对而言,是容易求出的。我们可以直接用快速幂取模的方法,对 nkmod1000,即可以得到我们所要求的答案。但是这题的难点主要是怎么求前三位,接下来我来重点讲一下怎么推导求前三位的方法。
推导
nk= 10lgnk= 10k∗lgn,设 k∗lgn=a+b(其中a是整数,b是小数)
那么 nk= 10lgnk= 10k∗lgn=10a+b=10a∗10b
我们可以知道 10a并不会改变前3位数的大小,仅仅改变位置,但是 10b中b是小数,所以会改变前3位数的大小
1=100<=10b<101=10(0<=b<1),这下问题就转化为如何求b?
如何求b呢
modf()函数
利用这个函数就可以把 k∗lgn的b算出来,那么我们还要分析一下 k∗lgn是否会出现数据范围爆出的问题,double可控制的是16位,而 k∗lgn<1e9.所以可实现。
AC代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
ll n,k,fir,res;
double x,y;
ll quick_mod(ll a,ll b,ll p){
ll num=a,sum=1;
while(b){
if(b&1){
sum=sum*num%p;
}
num=num*num%p;
b>>=1;
}
return sum;
}///a^b mod p*/
int main(){
int t,num=1;
cin>>t;
while(t--){
scanf("%lld%lld",&n,&k);
res=quick_mod(n,k,1000);///res表示后三位
y=modf((double)(k*log10(n)),&x);
fir=pow(10,y)*100;
printf("Case %d: %03lld %03lld\n",num++,fir,res);
}
return 0;
}