写在前面
刚写了几道不错的递归题,题目倒是不难,自己实现起来却有点困难,大佬们代码的思路很好,我倒是没想到递归可以这么精妙,递归确实好用啊!
P1010 幂次方
题目来源
思路
通过137和1315这两个样例,题目明确要求我们用递归/分治来写
拿1315举例,首先要找最接近1315的2次幂,很容易找到
2
10
2^{10}
210最接近1315,然后1315减去
2
10
2^{10}
210继续找最接近这个数的2次幂
最后就能得出上述式子1315=
2
10
+
2
8
+
2
5
+
2
1
+
2
0
2^{10}+2^8+2^5+2^1+2^0
210+28+25+21+20,当21时写成2,20时写成2(0)
思路是不难,重点是如何将次幂进行进一步划分呢?
我们就得用上递归了,当前数x大于
2
i
时
(
i
代表最接近
x
的次幂
)
,我们就将
i
放入循环中,进行下一次递归
2^i时(i代表最接近x的次幂),我们就将i放入循环中,进行下一次递归
2i时(i代表最接近x的次幂),我们就将i放入循环中,进行下一次递归
每次有参数递归,我们都需要输出
2
(
2(
2( 等到递归结束输出
)
)
) 即可,若当前数x减去2i不为0,则需要输出+
code
void f(int x){
for(int i=14;i>=0;--i){
if(x>=pow(2,i)){
if(i==1) cout << "2";
else if(i==0) cout << "2(0)";
else{
cout << "2(";
f(i);
cout << ")";
}
x-=pow(2,i);
if(x!=0) cout << "+";
}
}
}
P1498 南蛮图腾
题目来源
思路
这题看起来简单,实则做起来不容易·······
这题思路有很多,分治、递归、dfs都能写,我用的是递归+模拟的思路
观察样例:(右图是杨辉三角对2取模)
我们可以得出两个规律:
- 取模结果为1代表该点上有图形,取模结果为0代表该点上没有图形
- 分奇偶性讨论(最顶上的图形忽略,从第二行开始),奇数行的图形为/__\,偶数行的图形为/\
那么这题就可以做了,先写一个杨辉三角的数组,令开一个数组计算当前数对2取模
判断奇偶性,若取模结果为偶数则输出两个空格
若为奇数,则继续判断当前行是奇数还是偶数,奇数行的图形输出/__\,偶数行的图形输出/\
code
void solve(){
int n;cin >> n;
int k=pow(2,n);
int sum=0;
a[0][1]=b[0][1]=1;
for(int i=1;i<=k-1;++i) cout << " ";
cout << "/\\" << endl;
for(int i=1;i<=k-1;++i){
for(int j=1;j<=k-i-1;++j) cout << " ";
for(int j=1;j<=k;++j){
a[i][j]=a[i-1][j]+a[i-1][j-1];
b[i][j]=a[i][j]%2;
if(!b[i][j]) cout <<" ";
else{
if(i & 1){
sum++;
if(sum & 1) cout << "/_";
else cout << "_\\";
}
else{
cout << "/\\";
}
}
}
cout << endl;
}
return ;
}
P1928 外星密码
题目来源
思路
题目描述表明有嵌套的情况,我们首先考虑递归(递归对于嵌套问题很好用)
这题用字符读入比较方便,每次读入只可能有3种情况:
- 不为 ′ [ ′ 和 ′ ] ′ '['和']' ′[′和′]′,我们只需新开一个字符串s,让s加上这个字符
- 若为’[',读入一个整数x,将后面的字符进行进一步递归,将结果赋值给新字符串ss,让s加上x倍的ss
- 若为’]',返回字符串s
code
string dfs(){
string s,ss;
char ch;
while(cin >> ch){
if(ch!='['){
if(ch!=']') s+=ch;
else return s;
}
else{
int x;cin >> x;
ss=dfs();
for(int i=1;i<=x;++i) s+=ss;
}
}
}
void solve(){
cout << dfs();
return ;
}