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 }