您的位置:首页 > 其它

二分求幂,快速求解a的b次幂

2015-11-30 21:36 246 查看

一个引子

如何求得a的b次幂呢,那还不简单,一个for循环就可以实现!

void main(void)
{
int a, b;
int ans = 1;
cin >> a >> b;
for (int i = 1; i <= b; i++)
{
ans *= a;
}
cout << ans;
}


那么如何快速的求得a的b次幂呢?上面的代码还可以优化吗?

当然是ok的!下面就介绍一种方法-二分求幂。

二分求幂

所谓二分求幂,即是将b次幂用二进制表示,当二进制位k位为1时,需要累乘a的2^k次方。

下面优化一下上面的代码:

void main(void)
{
int a, b;
int ans = 1;
cin >> a >> b;
while (b != 0)
{
//当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存
if (b % 2 == 1)
{
ans *= a;
}
a *= a;
//每次除以2,转换成二进制位
b /= 2;
}
cout << ans;
}


举个例子,当b = 5时,b的二进制为101。

循环次数二进制位ans值a值b值
01011a5
11012a22
21012a41
310132a160
从上表我们可以直观的看出5次幂就可以转换为(2^0+2^2),即a的5次幂就转变为a的(2^0+2^2)次幂,即a的2^0与a的2^2的乘积。

再来个例子-巩固

此题来源于九度教程“人见人爱A^B”。

题目描述:

求A^B的最后三位数表示的整数。

输入:

输入数据包含多个测试实例,每个实例占一行,由两个正整数a和b组成,其中(1<=a,b<=10000),如果a = 0,被= 0,则表示输入数据结束,不做处理。

输出:

对于每个测试实例,输出a^b的最后三位表示的整数,每个输出占一行。

样例输入:

2 3

12 6

6789 10000

0 0

样例输出:

8

984

1

对于这道题,完全可以用上面的二分求解方法,可以仿照上面的代码进行实现。但是有一点需要注意的是,我们不肯能定义一个整型变量或者long long类型的变量取保存如样例给出的数据a = 6789,b=10000,a^b的计算结果。因为数字太庞大了,在整数范围内是无法表示的。所以我们可以只保存每次计算结果的后三位,因为最终结果的后三位取决于其中间值的后三位。

好吧,给出代码:

void main(void)
{
int a, b;
while ((cin >> a >> b))
{
int ans = 1;
if (a == 0 && b == 0)
break;
while (b != 0)
{
//当二进制位k位为1时,就累加a的2^k次方
if (b % 2 == 1)
{
ans *= a;
ans %= 1000;
}
a *= a;
a %= 1000;
//每次除以2,转换成二进制位
b /= 2;
}
cout << ans;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: