• 2的n次幂


    问题描述

    任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001。
      将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:137=2^7+2^3+2^0
      现在约定幂次用括号来表示,即a^b表示为a(b)
      此时,137可表示为:2(7)+2(3)+2(0)
      进一步:7=2^2+2+2^0 (2^1用2表示)
      3=2+2^0 
      所以最后137可表示为:2(2(2)+2+2(0))+2(2+2(0))+2(0)
      又如:1315=2^10+2^8+2^5+2+1
      所以1315最后可表示为:
      2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
    输入格式
      正整数(1<=n<=20000)
    输出格式
      符合约定的n的0,2表示(在表示中不能有空格)
    样例输入
    137
    样例输出
    2(2(2)+2+2(0))+2(2+2(0))+2(0)
    样例输入
    1315
    样例输出
    2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)


    思路

      简单点的话,老老实实算二进制,再输出;这里涉及到每位二进制的指数也要一起分解,即在分解我们的数的途中还要分解,明显的递归。

      但是也可以不用算出二进制,使用位运算直接对二进制进行操作,这里用 137 来演示,具体如下:

      首先我们知道 137 的二进制为:10001001

    1、获取最高位二进制

    1 for(e=0, now=1; now <= n; now<<=1, e++);

    这里的 e 表示当前二进制的位置,也就是我们需要的指数,初始化为 0 位;now 表示 2 的 n 次方,用来与我们输入的数 n 相比较,判断具体要移动多少位。这里我们循环结束后应该是这样子的:

    010001001  原数 137

    100000000  2 的 8 次方 256

    此时, e = 8, now = 256

    2、判断当前位是否是 0 位

    这是大概最精彩的部分

    1 for(;now>0;now>>=1, e--){
    2         if(now & n){
          // 继续
    3   }

    之前我们已经知道了 now 和 n 的二进制,接下来,当循环条件满足时,我们就不断将二进制左移(e--),同时将 now 与 n 按位与,得到如下结果:

    010001001  原数 137

    100000000  2 的 8 次方 256

    000000000  0

    判断条件为假,继续下一次循环:

    010001001  原数 137

    010000000  2 的 7 次方 128,因为我们右移了一位

    010000000  此时不为0

    判断条件为真,继续执行下面的内容,直到把当前的二进制读取完。

    下一次循环结果为

    010001001  原数 137

    001000000  2 的 6 次方 64

    000000000  此时为0

    一直下去......

    3、判断输出

     1 void fun(int n)
     2 {
     3     int now, e;
     4     for(e=0, now=1; now <= n; now<<=1, e++);
     5     cout<<"2";
     6     for(;now>0;now>>=1, e--){
     7         if(now&n){
     8             if(now > 2){      // now 大于2,说明指数大于2,还要继续分解
     9                 cout<<"(";
    10                 fun(e);       // 递归
    11                 cout<<")";
    12             }
    13             if(now == 2);      // 等于2时题目叫我们什么也不做
    14             else if(now == 1){    // 等于1是要输出指数0
    15                 cout<<"(0)";
    16             }
    17             /*
    18             当当前指数分解结束后,要用之前的数减去当前分解的指数,比            
    19             如这里137 = 2^7 + 2^3 + 2^0,在分解完2^7后,继续分解 
    20             2^3 + 2^0
    21             */
    22             n -= now;        
    23             if(n){         // 当然,如果可以继续分解的话,否则这里条件判断是假
    24                 cout<<"+2";
    25             }
    26         }
    27     }
    28 }                          

    完整代码

     1 #include<iostream> 
     2 
     3 using namespace std;
     4 
     5 void fun(int n)
     6 {
     7     int now, e;
     8     for(e=0, now=1; now <= n; now<<=1, e++);
     9     cout<<"2";
    10     for(;now>0;now>>=1, e--){
    11         if(now&n){
    12             if(now > 2){
    13                 cout<<"(";
    14                 fun(e);
    15                 cout<<")";
    16             }
    17             if(now == 2);
    18             else if(now == 1){
    19                 cout<<"(0)";
    20             }
    21             n -= now;
    22             if(n){
    23                 cout<<"+2";
    24             }
    25         }
    26     }
    27 }
    28 int main()
    29 {
    30     int n = 0;
    31     cin>>n;
    32     fun(n);
    33     
    34     return 0;
    35 }
    View Code

  • 相关阅读:
    PHP根据蜘蛛和设备进行适配不同界面
    destoon7.0招商地区聚合推送
    Destoon7.0产品栏目地区聚合推送插件
    Destoon7.0百度批量循环推送至百度
    PHP 实现随机图像功能
    PHP中$_SERVER参数用法总结
    关于destoon后台添加自定义功能+前台展示标签调用方法
    分类地区批量推送熊掌号+主动推送代码
    SpringMVC-SimpleDEMO
    SpringMVC工作流程
  • 原文地址:https://www.cnblogs.com/mabeyTang/p/9880305.html
Copyright © 2020-2023  润新知