快速幂
计算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.