之前学了汉诺塔,然后做了几道关于递归的题,一直感觉对递归一知半解,感觉递归的题不能100%做出来,但是做了这道题,感觉递归是有技巧的。
从思路讲起:
首先这是一个简单的求幂的方法。
我们如何得到这个式子呢?
7的二次方是 111,也就是说我们可以把二进制的形式转换成这个公式。
7的这个例子太特殊了,我们想一个普遍的例子:11
11的二进制是 1011,所以11可以写成
这个问题就迎刃而解了。那么怎么得到二进制呢?通过大家熟悉的 先对二取余,再除二就可以得到这个二进制数。
这个题还有一个小点就是,题中给的都是从高位到地位的二进制输出,我们对2取余得到的正好是高位的1.所以我们可以直接通过从后查找的方式,查找1的下标,就恰好可以得到这个关系。
例如: 上边11的例子,求出来的二进制应该为1011,但是通过模2除二,得到的是1101,这里我们不用取反,直接从后查找,查到的1的下标依次为3,1,0.正好符合要求。
第三点就是输出格式的问题,我们可以很轻松的将这道题和递归联系起来。
这个公式中的7和3是大于2的,所以我们可以通过2和1的组合表示7和3
也就是
所以可以表示为
最后粘代码
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
void pow2(int n)
{
if(n==1) //这里的 1代表2的1次幂
cout<<"2";
else if(n==2) //2代表2的2次幂
cout<<"2(2)";
else if(n==0)
cout<<"2(0)"; //0代表2的0次幂
else //2的高次幂可以由 0,1,2来组合表示
{
string res;
while(n)
{
res+=n%2+'0';
n/=2;
}
//cout<<res<<endl; //转换成二进制后的结果(逆序)
int index;
while((index=res.rfind("1"))!=string::npos) //从后往前查找
{
if(index>2) //为什么要以2为分界点呢?因为二次幂以下都可以直接表示,但是3次幂就要组合表示。所以输出格式有所变化。
{
cout<<"2(";
pow2(index);//在这里递归输出
res[index]='0';
cout<<")";
if((index=res.rfind("1"))!=string::npos) //最后一个加号不用输出
cout<<"+";
}
else
{
pow2(index);
res[index]='0';
if((index=res.rfind("1"))!=string::npos)
cout<<"+";
}
}
}
}
int main()
{
int n;
while(cin>>n)
{
if(n==1)
cout<<"2(0)";
else if(n==2)
cout<<"2";
else if(n==0)
cout<<"0";
else
pow2(n);
cout<<endl;
}
return 0;
}


京公网安备 11010502036488号