二的幂次方

Description

任何一个正整数都可以用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(21用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)
Input
每个测试文件只包含一组测试数据,每组输入一个正整数n(n<=20000)。
Output
对于每组输入数据,输出符合约定的n的0,2表示。(在表示中不能有空格)
Sample Input 1
137
Sample Output 1
2(2(2)+2+2(0))+2(2+2(0))+2(0)
Sample Input 2
73
Sample Output 2
2(2(2)+2)+2(2+2(0))+2(0)
解题思路:
(1)统计该数字的中二进制1的位数;可以利用 
1)与运算
2)右移
实际上这是计算机思维,利用数学思维则是利用
1)用该数%2,再判断余数是否为1;
2)将该数n/2   并再次赋值给n   即n /= 2;
这两种其实是一样的,后面这种的数学思维最后转化在计算机里仍是利用 
与运算    和   右移运算;
(2)不断递归,观察到题目最后结果只有2(2),和2和2(0)这三种形式,故递归的最终结束条件就是这三个;
 
代码如下:
 1 #include<iostream>
 2 using namespace std;
 3 
 4 int n ,tmp;
 5 void digui(int n)   //递归函数
 6 {
 7     int i ,count1;
 8     int flag[32];
 9     i = 0 , count1 = 0;
10     while(n!=0)          //不断用与运算n的每位中的1,并记录其序号,结束条件就是n右移到没有位数,即n==0 时退出循环
11     {
12         if(n&1)    //利用与运算,判断该二进制位是否为1;
13         {
14             flag[count1] = i;   //将1的序号记录下来;
15             count1++;
16         }
17         n>>=1;    //向右移一位;
18         i++;
19     }
20     
21 
22     for( i = count1 - 1;i >= 0;i--)
23     {
24         if(flag[i]==0)     //如果序号为0  ,即输出2(0);
25         {
26             cout<<"2(0)";
27         }else
28         if(flag[i]==1)   //如果序号为1  ,即输出2(1);
29         {
30             cout<<"2";
31         }else
32         if(flag[i]==2)   //如果序号为2  ,即输出2(2);
33         {
34             cout<<"2(2)";
35         }else
36         {
37             cout<<"2(";
38             digui(flag[i]);   //若不满足递归结束条件,继续递归,直到将全部分解成2(0),2,2(2)这三种形式;
39             cout<<")";
40         }
41         if(i!=0) cout<<"+";
42     }
43 }
44 int main()
45 {
46     cin>>n;     //题目只有一组数字且n<=20000,用int类型即可;
47     digui(n);  //递归;
48     return 0;
49 }
 
原文地址:https://www.cnblogs.com/yewanting/p/10537078.html