LightOJ - 1282(n^k的前三位數字和後三位數字)

    You are given two integers: n and k, your task is to find the most significant three digits, and least significant three digits of nk.


Input

    Input starts with an integer T (≤ 1000), denoting the number of test cases.

    Each case starts with a line containing two integers: n (2 ≤ n < 231) and k (1 ≤ k ≤ 107).


Output

    For each case, print the case number and the three leading digits (most significant) and three trailing digits (least significant). You can assume that the input is given such that nk contains at least six digits.
Sample Input

    5

    123456 1

    123456 2

    2 31

    2 32

    29 8751919
Sample Output

    Case 1: 123 456

    Case 2: 152 936

    Case 3: 214 648

    Case 4: 429 296

    Case 5: 665 669

題意如標題
後三位好說,快速冪取個模
前三位我們可以這樣:直接作爲正整數n^k來取很難,因爲這個數會很大並且無法捨去後面的數字來做優化,我們可以轉化爲小數:
log10(n^k)=k*log10(n),然後又因爲n^k=z*10^x,即有log10(n^k)=log10(z)+x,並且在n^k=z*10^x中,x(即10^x)只貢獻了該整數的位數,真正的前三位
都被實數z貢獻了。
所以有10^(log10(z))的個位和小數點後兩位即是n^k的前三位(因爲是用科學計數法的,所以z肯定有且只有一個整數位,即只有個位,其餘都是小數位)

所以根據式子log10(z)=(double)k*log10(n)-(LL)k*log10(n)即可

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=2e5+3;
LL n,k;

LL quick(LL x,LL a)
{
    LL res=1,MOD=1000;
    while(a)
    {
        if(a&1)res=x*res%MOD;
        x=x*x%MOD;
        a>>=1;
    }
    return res%MOD;
}

int main()
{
    int T;
    scanf("%d",&T);
    int cas=0;
    while(T--)
    {
        scanf("%lld%lld",&n,&k);
        LL a1,a2=quick(n,k),z=k*log10(n);

        double x=k*log10(n)-(double)z;

        x=pow(10,x)*100;//printf("z=%lld x=%f\n",z,x);
        a1=x;
        printf("Case %d: %lld ",++cas,a1);
        if(a2>=100)printf("%lld\n",a2);
        else if(a2>=10)printf("0%lld\n",a2);
        else printf("00%lld\n",a2);
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章