zoukankan      html  css  js  c++  java
  • 2的次幂表示【递归算法训练】

    【一个比较经典的算法题目】
    题目链接:
    http://lx.lanqiao.org/problem.page?gpid=T235
    http://noi.openjudge.cn/ch0202/8758/
     
    问题描述
      任何一个正整数都可以用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表示为:2(7)+2(3)+2(0)的程序。
    关于加号的输出:可以考虑判断当前项是否二进制序列的最高位(传入下一层的数是0)。是最高位则当前项左侧不输出“+”,否则在当前项左侧输出“+”.
    关于把指数也转变为0和2的序列:在输出每一项时判断指数是否超过1,超过则先输出“2(”,然后把该指数与0传入递归函数,递归显示该指数的表示。然后在输出后半边括号。
     
    嗯可以先看看递归输出一个整数的二进制序列:
    程序0:
    #include <stdio.h>
    void fun(int n)
    {
    int t;
    if(n==0) return; else { t=n%2; fun(n/2); printf("%d",t); } } int main() { fun(5); return 0; }
    程序一:实现将137表示为:2(7)+2(3)+2(0)的程序.
     1 #include <stdio.h>
     2 void toBinary(int n,int x);
     3 int main()
     4 {
     5     int n;
     6     freopen("out1.txt","w",stdout);
     7     n=1;
     8     while(n<=255)
     9     {
    10         //scanf("%d",&n);
    11         printf("%d---->",n);
    12         toBinary(n,0);
    13         printf("
    ");
    14         n++;
    15     }
    16     
    17     return 0;
    18 }
    19 void toBinary(int n,int x)
    20 {
    21     int t;
    22     if(n==0)
    23         return;
    24     else
    25     {
    26         t=n%2;
    27         toBinary(n/2,x+1);
    28         if(t)
    29         {
    30             if(x==1)
    31             {
    32                 if(n/2==0)
    33                     printf("2");
    34                 else printf("+2");
    35             }
    36             else
    37             {
    38                 if(n/2==0)
    39                     printf("2(%d)",x);
    40                 else printf("+2(%d)",x);
    41             }
    42         }
    43     }
    44 }
    程序二:完整程序的实现。
     1 #include <stdio.h>
     2 void toBinary(int n,int x);
     3 int main()
     4 {
     5     int n;
     6     /*scanf("%d",&n);
     7     toBinary(n,0);*/
     8     
     9     freopen("out2.txt","w",stdout);
    10     n=1;
    11     while(n<=255)
    12     {
    13         //scanf("%d",&n);
    14         printf("%d---->",n);
    15         toBinary(n,0);
    16         printf("
    ");
    17         n++;
    18     }
    19     
    20     return 0;
    21 }
    22 void toBinary(int n,int x)
    23 {
    24     int t;
    25     if(n==0)
    26         return;
    27     else
    28     {
    29         t=n%2;
    30         toBinary(n/2,x+1);
    31         if(t)
    32         {
    33             if(x==1)
    34             {
    35                 if(n/2==0)
    36                     printf("2");
    37                 else printf("+2");
    38             }
    39             else
    40             {
    41                 if(n/2==0)
    42                 {
    43                     //printf("2(%d)",x);
    44                     if(x==0) printf("2(0)");
    45                     else
    46                     {
    47                         printf("2(");
    48                         toBinary(x,0);
    49                         printf(")");
    50                     }
    51                 }
    52                 else
    53                 {
    54                     //printf("+2(%d)",x);
    55                     if(x==0) printf("+2(0)");
    56                     else
    57                     {
    58                         printf("+2(");
    59                         toBinary(x,0);
    60                         printf(")");
    61                     }
    62                 }
    63             }
    64         }
    65     }
    66 }

     更新:上述代码的if逻辑可以简化。

     1 #include <stdio.h>
     2 void toBinary(int n,int x);
     3 int main()
     4 {
     5     int n;
     6     /*scanf("%d",&n);
     7     toBinary(n,0);*/
     8     
     9     freopen("out2.txt","w",stdout);
    10     n=1;
    11     while(n<=255)
    12     {
    13         //scanf("%d",&n);
    14         printf("%d---->",n);
    15         toBinary(n,0);
    16         printf("
    ");
    17         n++;
    18     }
    19     
    20     return 0;
    21 }
    22 void toBinary(int n,int x)
    23 {
    24     int t;
    25     if(n==0)
    26         return;
    27     else
    28     {
    29         t=n%2;
    30         toBinary(n/2,x+1);
    31         if(t)
    32         {
    33             if(x==1)
    34             {
    35                 if(n/2==0)
    36                     printf("2");
    37                 else printf("+2");
    38             }
    39             else
    40             {
    41                 if(n/2!=0)printf("+");
    42                 
    43                 if(x==0) printf("2(0)");
    44                 else
    45                 {
    46                     printf("2(");
    47                     toBinary(x,0);
    48                     printf(")");
    49                 }
    50             }
    51         }
    52     }
    53 }

    2019年3月15日,刘俊东童鞋写了一段代码解决这道题,感觉虽有不足,但也算是思路新奇,可以一睹风采:

     1 #include <stdio.h>
     2 int mi(int a,int b)
     3 {
     4     int i,sum=1;
     5     for(i=0;i<b;i++)
     6       sum=sum*a;
     7     return sum;  
     8 }
     9 void fun(int n)
    10 {
    11     int t;
    12     for(int i=0;i<16;i++)
    13     {
    14         t=i;
    15         if(mi(2,i)>n)
    16         {t--;break;}
    17     }
    18     if(t==0) printf("2(0)");
    19     if(t==1) printf("2");
    20     if(t>1) 
    21     {
    22         printf("2(");
    23         fun(t);
    24         printf(")");
    25     }
    26     if(n!=mi(2,t)) 
    27     {    
    28         printf("+");
    29         fun(n-mi(2,t));
    30     }
    31 }
    32 int main(int argc, char *argv[])
    33 {
    34     int p;
    35     scanf("%d",&p);
    36     fun(p);
    37     return 0;
    38 }
    View Code
     
  • 相关阅读:
    HDU5818 Joint Stacks 左偏树,可并堆
    HDU1512 ZOJ2334 Monkey King 左偏树
    BZOJ3626 [LNOI2014]LCA 树链剖分 线段树
    BZOJ4034 [HAOI2015]树上操作 树链剖分
    BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组
    BZOJ1968 [Ahoi2005]COMMON 约数研究 数论
    BZOJ2759 一个动态树好题 LCT
    BZOJ3669 [Noi2014]魔法森林 LCT
    HDFS要点
    HDFS(0.20.2)运营中急救方案
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/4417467.html
Copyright © 2011-2022 走看看