Description
说明:A^B的含义是“A的B次方”
Input
Output
Sample Input
2 3 12 6 6789 10000 0 0
Sample Output
8 984 1
直接用尾数来做,直接算肯定溢出。
#include <stdio.h>
int main()
{
int A, B;
while (scanf("%d%d", &A, &B)!= EOF && A && B){
int sum = 1;
for (int i = 1; i <= B; i++){
if (sum > 1000){
sum = sum % 10 + (sum / 10) % 10 * 10 + (sum / 100) % 10 * 100;
// printf(">1000 sum = %d\n", sum);
sum *= A;
}
else sum *= A;
}
sum = sum % 10 + (sum / 10) % 10 * 10 + (sum / 100) % 10 * 100;
printf("%d\n", sum);
}
}
后来再看了看此题目,现有如下理解
由于(A*B)%C == (A%C*B%C)%C 此题就很好理解了,只要取末尾3尾数不停地做幂运算。
由于我用了多组数据,sum=1一步是对每次的残留清空,这一步蛮重要的。
#include <stdio.h>
// (A*B)%C == (A%C*B%C)%
int sum;
int _pow (int a,int b)
{
if (sum > 1000) sum = sum % 1000;
while (b){
sum *= a;
if (sum > 1000) sum = sum % 1000;
b--;
return sum = <span style="font-family: Arial, Helvetica, sans-serif;">_pow</span>(a,b);
}
return sum;
}
int main()
{
int a,b,ends;
while (scanf("%d%d", &a, &b)!=EOF && a && b){
sum = 1; //很nice的一步,去了残留
ends = <span style="font-family: Arial, Helvetica, sans-serif;">_pow</span><span style="font-family: Arial, Helvetica, sans-serif;">(a,b);</span>
printf("%d\n", ends);
}
}
缺点:该算法 利用公式a*b%c=((a%c)*b)%c,这样每一步都进行这种处理,这就解决了a^b可能太大存不下的问题,但这个算法的时间复杂度依然没有得到优化
求x^31
x ^ 2 = x * x
x ^ 4 = (x ^ 2) * (x ^ 2)
x ^ 8 = (x ^ 4) * (x ^ 4)
x ^ 16 = (x ^ 8) * (x ^ 8)
x ^ 31 = (x ^ 16) * (x ^ 8) * (x ^ 4) * (x ^ 2) * x
要8次乘法。
求x^31
x ^ 2 = x * x
x ^ 4 = (x ^ 2) * (x ^ 2)
x ^ 8 = (x ^ 4) * (x ^ 4)
x ^ 10 = (x ^ 8) * (x ^ 2)
x ^ 20 = (x ^ 10) * (x ^ 10)
x ^ 30 = (x ^ 20) * (x ^ 10)
x ^ 31 = (x ^ 30) * x
只要7次乘法。
求x^31
x ^ 2 = x * x
x ^ 4 = (x ^ 2) * (x ^ 2)
x ^ 8 = (x ^ 4) * (x ^ 4)
x ^ 16 = (x ^ 8) * (x ^ 8)
x ^ 32 = (x ^ 16) * (x ^ 16)
x ^ 31 = (x ^ 32) / x
只要6次乘或除法。
这里体现了一个幂指数为奇偶的情况,当为奇时,先化成偶数,即 a^n %c = (a * a ^n-1)%c = (a % c * a ^n-1 %c ) %c
为偶数时取对半 即 a ^ n % c = ( a ^ n/2 * a ^ n / 2) %c
这是大体上快速幂的逻辑
int fastpow(int x, int n,int mods) //快速幂带取余
{
while (n > 0) {
if (n & 1){ // n & 1 等价于 (n % 2) == 1
x = x % mods;
sum *= x;
sum = sum % mods;
n-- ;
}
else {
x *= x;
x = x % mods;
n /= 2; // n >>= 1 等价于 n /= 2
}
}
sum = sum % mods;
return sum; //sum我在外部定义的;
}