UVa 11029 - Leading and Trailing 数学题(求n^k的前N位和后N位)

/**
* 题意求n^k的前三位和后三位:
*
* 一开始就是把n变成小数,循环运算,然后再乘1000取前三位,结果TLE。。。
* 总是忘了用log神器。。。
*
* 首先,后三位好求。 快速幂取模就行。或者循环取模应该也不会超市。
*
* 再者,前三位:
*      这里就要用到log神器了。。。
*    设 n^k = A   两边取对数有: lgA = k * lgn;
*    则 原来的n^k 就可以表示成 10^(lgA) 即 10^(k*lgn) 亦即 pow(10, k*lgn);
*    当然这样还是不行的。  再看看 k*lgn
*    如果把k*lgn 分解成整数部分z和小数部分d的话,也就是 k*lgn = z + d;
*    原来的pow(10, k*lgn)就变成了pow(10, z + d);
*    又因为,pow(10, z) (z为整数)是不影响n^k的具体数字的,也就是说pow(10, z)的值是1000..(z个零)
*    所以我只需要用到小数部分d,这样pow(10, d)就不会溢出了,但是要如何得到前三位呢?
*    方法 pow(10, 2 + d) 其实就是乘100, 因为pow(10, d)得到的是个大于1小于10的整数。
*    最后就还剩如何表示d了。  方法: d = fmod(k * log10((double)n), 1)
*/


#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <queue>
#include <map>
#include <algorithm>
#define INF 0x7fffffff
#define MODX 1000
using namespace std;

int qmod(int p, int n) {
    int ans = 1;
    while(n > 0) {
        if(n & 1) {
            ans = (ans % MODX) * (p % MODX) % MODX;
        }
        p = (p % MODX) * (p % MODX) % MODX;
        n >>= 1;
    }

    return ans;
}

int main()
{
    int t, num;
    int head, latter, times;
    scanf("%d", &t);
    while(t --) {
        scanf("%d%d", &num, ×);
        /* the last 3 digits. */
        latter = qmod(num, times);

        /* the first 3 digits. */
        head = (int)pow(10, 2 + fmod(times * log10((double)num), 1));

        printf("%d...%03d\n", head, latter);
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值