这道题算是个里程碑,记录一下。看过许多编程大佬的刷题经验,有一个共同点就是不遇到不会轻易去看题解,而是去花大量的时间去思考,神奇的是,当时不会的题目天天琢磨往往会在不经意间想到AC的办法。但每次当自己遇到问题的时候,但想了很久总是想不明白总会忍不住去看题解,而这样不仅对自己编程水平提升帮助不大,而且AC了也没成就感(刷题的动力不就是为了获得AC后的快乐吗)。这次像平时一样苦苦寻找不到决绝的办法,这时心中总会有两种思想在作斗争,一种是看看题解,还有一种想法就是“总感觉自己可以,再撑一会”。这回后者更为强烈,于是选择再多坚持会,终于AC了,开心。
题目描述
我们要求找出具有下列性质数的个数(包含输入的正整数 n)。
先输入一个正整数 n(n≤1000),然后对此正整数按照如下方法进行处理:
-
不作任何处理;
-
在它的左边加上一个正整数,但该正整数不能超过原数的一半;
-
加上数后,继续按此规则进行处理,直到不能再加正整数为止。
输入格式
1 个正整数 n(n≤1000)
输出格式
1 个整数,表示具有该性质数的个数。
输入输出样例
输入:6
输出:6
满足条件的数为
6,16,26,126,36,136
思路分析:
最终结果为线条总数加1,而在递归算法中,当输入数值越大时,6被重复计算的次数就越多,而通过递推就可以实现,把计算过的6的结果保存起来,用的时候直接取用就行。
递归算法:
#include<iostream>
using namespace std;
int a[1005];
int cnt = 0, cnt1 = 0,t;
int fun(int k)
{
if(k != t)
{
cnt++;
}
for(int i = k/2; i >= 1; i--)//小于等于k值的数继续递归
fun(i);
}
int main()
{
int n;
cin >> n;
t = n;
fun(n);
cout << cnt+1 << endl;//父节点单独考虑
return 0;
}
一般递归的问题都可以转化为递推。而二者的区别就是,递推可以存入之前计算过的数据。而递归如果不做处理,可能对同一个数据重复计算导致下图中超时的情况。
递推算法:
#include<iostream>
using namespace std;
int a[1005];
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; i++)
{
for(int j = i/2; j >= 1; j--)
a[i] += a[j];
a[i] +=1;
}
cout << a[n] << endl;
return 0;
}
很多时候坚持并不一定能获得结果,这取决于对自己的了解程度,该放弃的时候放弃,该坚持的时候坚持(感觉说了句废话【狗头】)。