人见人爱A^B
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 58164 Accepted Submission(s): 38668
Problem Description
求A^B的最后三位数表示的整数。
说明:A^B的含义是“A的B次方”
Input
输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。
Output
对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行。
Sample Input
2 3
12 6
6789 10000
0 0
Sample Output
8
984
1
//溢出肯定的,所以不能用老办法,看了许多大佬的分析,我总结了一下:
1,有一个数学规律:结果每次对1000取余,后三位不变,不懂个话,补一下数论知识(同余运算及其基本性质),所以说数学真滴?分重要鸭。
#include <iostream>
#include<cmath>
#include<iomanip>
using namespace std;
int main()
{
int a,b,c,d;
while(cin>>a>>b&&(a!=0&&b!=0))
{
int i,sum=1;
for(i=0;i<b;i++)
{
sum*=a;
if(sum>100)
sum%=1000;
}
cout<<sum<<endl;
}
}
2.快速幂:
快速幂可以高效的计算幂运算。如果我们使用循环来计算的话,那么时间复杂度就是 O(n) ,使用快速幂的话就只用 O(log n)。
如果我们求解 2^k。可以将其表示为
x^n =( (x²)²…)
只要做k次平方运算就可以了,由此我们可以想到,先将n表示为2的幂方次之和
n = 2^k1 + 2^k2 + 2^k3…
就有
x^n = x(2k1) x(2k2) x(2k3)…
详情参见快速幂讲解文章
其中n&10表示偶数,n&11为奇数,这是进制运算
n>>1表示n/=2
#include<stdio.h>
int mod_pow(int x, int n,int mod)
{ //快速幂
int res = 1;
while( n > 0 ){
if( n & 1 ) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
int main()
{
int m,n;
while(scanf("%d%d",&m,&n),n||m)
printf("%d\n",mod_pow(m,n,1000));
return 0;
}