蓝桥2017决赛:小数第n位(快速幂和快速幂取模核心思想)

快速幂

计算x^y次幂
普通方法,乘x次,时间复杂度为O(n)

while(y--)
   x*=x;

快速幂方法,时间复杂度为O(log2n)
当y为偶数时,转换为(x^2)的(y/2)次方
当y为奇数时,转换为(x^2)的(y/2)次方,再乘x

long long quick_pow(long long x,long long y)
{
    long long ans=1;  //返回的结果
    while(y)   //当指数大于0的时候进行运算
    {
        if(y&1) //y和1 进行&运算,相当于y%2
        {
            ans=ans*x;  //y为奇数时,要再乘x
        }
        x*=x;  //x平方
        y>>=1;  //y右移一位,相当于y/2
    }
    return ans;
}

快速幂取模

计算x^y%m,运用公式
在这里插入图片描述

long long quick_pow(long long x,long long y,long long m)
{
    long long ans=1;  //返回的结果
    while(y)   //当指数大于0的时候进行运算
    {
        if(y&1) //y和1 进行&运算,相当于y%2
        {
            ans=ans*x%m;  //y为奇数时,要再乘x
        }
        x=x*x%m;  //x平方
        y>>=1;  //y右移一位,相当于y/2
    }
    return ans;
}

准备工作做完,直接挂题

[蓝桥杯2017决赛]小数第n位

  • Description
    我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数。
    如果我们把有限小数的末尾加上无限多个0,它们就有了统一的形式。
    本题的任务是:在上面的约定下,求整数除法小数点后的第n位开始的3位数
  • Input
    输入存在多组测试数据,对于每组测试数据:
    输入一行包含三个整数:a b n,用空格分开。a是被除数,b是除数,n是所求的小数后位置
    0<a,b,n<1000000000
  • Output
    对于每组测试数据:输出3位数字:a除以b,小数后第n位开始的3位数字。

分析
题目求的是包括n的三位小数,我们直接把这三位数变成整数,然后%1000就行
变成整数的过程:a/b*pow(10,n+2)%1000
由公式 a/b%m=a%(b×m)/b
最终转换为求 a×pow(10,n+2)%(1000×b)/b

破案了,这是个数学问题!

  • AC代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll quick_pow(ll a,ll b,ll mod)
{
    ll ans=1;
    while(b)
    {
        if(b&1)  ans=ans*a%mod;

        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int main()
{
    ll a,b,n;
    while(cin>>a>>b>>n)
    {
        ll mod=b*1000;
        ll Pow=quick_pow(10,n+2,b*1000);
        ll ans=(a%mod*Pow%mod)%mod/b;
        printf("%03d\n",ans);
        //cout<<ans<<endl;
    }
    return 0;
}

本文参考
https://blog.csdn.net/weixin_43739438/article/details/99001657?ops_request_misc=&request_id=&biz_id=&utm_source=distribute.pc_search_result.none-task.
https://blog.csdn.net/weixin_43336281/article/details/90381229.
在这里插入图片描述

发布了14 篇原创文章 · 获赞 3 · 访问量 538

猜你喜欢

转载自blog.csdn.net/qq_44577309/article/details/104476728