LightOJ 1282 Leading and Trailing(对数转化)

题意:

给n,k,求nk的前三位和后三位

思路:

后三位直接快速幂对1000取模就行了,主要是前三位怎么求。

前三位:
一个整数x可用科学计数法表示为10r*a
由科学计数法可知r为整数,a为1-10之间的整数

设nk=x=10r*a
两边取对数得k log10(n)=log10(x)=log10(a)+r
因为r是整数,a小于10,所以r是整数部分,log10(a)是小数部分

因为是小数部分,可以利用强制类型转化的技巧直接求出小数部分:
log10(a)=log10(x)-(int)log10(x)=k log10(n)-(int)(k log10(n))

则a等于10klog10(n)-(int)(klog10(n))
(int)(a*100)即为nk的前三位

ps:
有个坑点就是后三位可能是027这种有前导零的,前导零也要输出。

code:
#include<bits/stdc++.h>
using namespace std;
const int mod=1e3;
int ppow(int a,int b){//快速幂
    a%=mod;
    int ans=1;
    while(b){
        if(b&1){
            ans=ans*a%mod;
        }
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int getfront(int n,int k){
    return (int)(pow(10.0,k*log10(n)-(int)(k*log10(n)))*100);
}
signed main(){
    int T;
    scanf("%d",&T);
    int cas=1;
    while(T--){
        int n,k;
        scanf("%d%d",&n,&k);
        printf("Case %d: ",cas++);
        printf("%d %03d\n",getfront(n,k),ppow(n,k));//后三位可能要输出前导零
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值