码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-11-30 22:13:47      阅读:335      评论:0      收藏:0      [点我收藏+]

标签:

一个引子

如何求得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值
0 101 1 a 5
1 101 2 a2 2
2 101 2 a4 1
3 101 32 a16 0

从上表我们可以直观的看出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;
    }
    
}

 

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

标签:

原文地址:http://www.cnblogs.com/tgycoder/p/5008480.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!