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


    一个引子

    如何求得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;
        }
        
    }
  • 相关阅读:
    CH1301 邻值查找【set应用】
    poj1185 炮兵阵地【状压DP】
    codeforces#516 Div2---ABCD
    2017ACM-ICPC沈阳区域赛
    poj2411 Mondriaan's Dream【状压DP】
    hdu2196 Computer【树形DP】【换根法】
    poj3345 Bribing FIPA【树形DP】【背包】
    poj1463 Strategic game【树形DP】
    poj1191 棋盘分割【区间DP】【记忆化搜索】
    CH5E09 能量相连【区间DP】
  • 原文地址:https://www.cnblogs.com/tgycoder/p/5008480.html
Copyright © 2020-2023  润新知