LightOJ - 1282 Leading and Trailing (快速幂 + 取对数求大数前三位)

题目链接 : http://lightoj.com/volume_showproblem.php?problem=1282


题目大意:给出n和k要让你求n^k的前三位以及后三位分别是什么。

题目思路:求后三位用快速幂对1000取膜可以很快取得,本题的难点在于求前三位,这里需要运用到一些数学知识;

我们可以知道 n^k = 10 ^ a  = 10^m * 10 ^ q(此处a为浮点数,m为a的整数部分,q为a的小数部分),m便是决定这个数的位数,q决定每一位的值;

求解q的方法:同时对等式两边取对数,可以得到k*log10(n) = m + log10(q);则x = log10(q) = k*log10(n) - m;接着另 x = pow(10,x)即可求得q,最后再乘上100,便是所要求的数的前三位了。


AC代码如下 :


#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define FIN freopen("in.txt","r",stdin)
#define fuck(x) cout<<'['<<x<<']'<<endl
using namespace std;
typedef long long LL;
typedef pair<int,int>pii;
const int MOD = 1000;

int quick_pow(int x,int n,int mod){
    int res = 1;
    if(x > mod)
        x%=mod;
    while(n){
        if(n&1) res = (res*x)%mod;
        x = (x*x)%mod;
        n >>= 1;
    }
    return res;
}

int T;
int n,k;

int main(){
    //FIN;
    scanf("%d",&T);
    int cas = 1;
    while(T--){
        scanf("%d%d",&n,&k);
        int las = quick_pow(n,k,MOD);//快速幂求得后三位;
        double most =  k*log10(n) - (LL)(k*log10(n));//按上述方法取对数求得前三位;
        most = pow(10.0,most);
        printf("Case %d: %d %03d\n",cas++,(int)(most*100),las);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值