Leading and Trailing(简单数论)

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).

题意:求nk的前三位和后三位

思路:
前三位:快速幂+模1000就可以得出结果
后三位:看到题解,感觉他的思路很巧妙——记nk=10t,这里t为浮点型数据,分为整数部分x和小数部分y,即nk=10x+y=10x×10y,其中10y<10,它的整数部分只有一位,这里其实可以看成答案的科学记数法表示:nk=10y×10x,所以我们只用把y算出来,然后10y×100取整就是所求答案

//算10y这里用到了pow()函数

#include <iostream>
#include <string.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<vector>
typedef long long LL;
using namespace std;
#define chl (root<<1)
#define chr ((root<<1)|1)
#define mid ((l+r)>>1)
const LL INF=2e9;
const int manx=1e6+10;
int _pow(int a,int b)
{
    int ans=1;
    a%=1000;
    while(b)
    {
        if(b&1)
            ans=(ans*a)%1000;
        a=(a*a)%1000;
        b>>=1;
    }
    return ans;
}
int main()
{
    double n;
    int m,t;
    scanf("%d",&t);
    for(int i=1; i<=t; i++)
    {
        scanf("%lf%d",&n,&m);
        double p=m*log10(n);
        double ans=pow(10,p-(int)p)*100;
        printf("Case %d: ",i);
        printf("%03d %03d\n",(int)ans,_pow(n,m));
    }
}

或则我们算快速幂的时候,我们对存结果的变量做点手脚,一样定义成double型,但是每次计算完后小数点前进几位,一直保证它只有3为整数

//log10(a)的结果取整就是 a的位数-1

#include <iostream>
#include <string.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<vector>
typedef long long LL;
using namespace std;
#define chl (root<<1)
#define chr ((root<<1)|1)
#define mid ((l+r)>>1)
const LL INF=2e9;
const int manx=1e6+10;
int _pow(int a,int b)
{
    int ans=1;
    a%=1000;
    while(b)
    {
        if(b&1)
            ans=(ans*a)%1000;
        a=(a*a)%1000;
        b>>=1;
    }
    return ans;
}
double turna(double a)
{
    int i,j=1;
    for(i=0; i<(int)(log10(a))-2; i++,j*=10);
    //for(i=0; i<(int)(log(a)/log(10.0))-2; i++,j*=10);
    return a/j;
}
double __pow(double a,int b)
{
    double ans=1;
    a=turna(a);
    while(b)
    {
        if(b&1)
            ans=turna(ans*a);
        a=turna(a*a);
        b>>=1;
    }
    return ans;
}
int main()
{
    double n;
    int m,t;
    scanf("%d",&t);
    for(int i=1; i<=t; i++)
    {
        scanf("%lf%d",&n,&m);
        double ans=__pow(n,m);
        printf("Case %d: ",i);
        printf("%03d %03d\n",(int)ans,_pow(n,m));
    }
}
发布了52 篇原创文章 · 获赞 26 · 访问量 3168

猜你喜欢

转载自blog.csdn.net/qq_43803508/article/details/102646781