我们要求找出具有下列性质数的个数(包括输入的自然数n)。
先输入一个自然数n(n≤1000),然后对此自然数按照如下方法进行处理:
1) 不作任何处理;
2) 在它的左边加上一个自然数,但该自然数不能超过原数的一半;
3) 加上数后,继续按此规则进行处理,直到不能再加自然数为止。
输入:自然数n(n≤1000)
输出:满足条件的数
【输入样例】
6 满足条件的数为 6 (此部分不必输出)
16
26
126
36
136
【输出样例】
6
用8为例画出的搜索树
直接将每一个满足条件的数,输出
#include <iostream>
using namespace std;
int a[1005];
void dfs(int k)
{
int i = 0;
for (i = k; i >= 1; i--)
cout << a[i];
cout << endl;
for (i = 1; i <= a[k] / 2; i++)
{
a[k + 1] = i;
dfs(k + 1);
}
}
int main()
{
int n;
cin >> n;
a[1] = n;
dfs(1);
return 0;
}
按照题意输出
思路一 数的计数递归
#include <stdio.h>
int total = 0;
void func(int n)
{
total++;
if (n == 1)
return;
for (int i = 1; i <= n / 2; i++)
func(i);
}
int main()
{
int n;
scanf("%d", &n);
func(n);
printf("%d", total);
return 0;
}
思路二 Fibonacci 递归
#include <stdio.h>
int func(int n)
{
if (n == 1 || n == 2)
{
return n;
}
else
{
if (n % 2 == 0)
return (func(n - 1) + func(n / 2));
else
return func(n - 1); //2n和2n-1个个数相同
}
}
int main()
{
int n;
scanf("%d", &n);
printf("%d\n", func(n));
return 0;
}
思路三 通过数组模拟实现
#include <stdio.h>
int a[1005] = {0};
int func(int n)
{
a[1] = 1;
for (int i = 2; i <= n; i++)
{
if (i % 2 == 0)
a[i] = a[i - 1] + a[i / 2];
else
a[i] = a[i - 1];
}
return a[n];
}
int main()
{
int n;
scanf("%d", &n);
printf("%d\n", func(n));
return 0;
}
思路四 数的计数记忆化搜索
#include <stdio.h>
int f[1005] = {0};
int func(int n)
{
if (f[n] != 0)
return f[n];
int s = 1; //本身也算一个
for (int i = 1; i <= n / 2; i++)
s = s + func(i);
f[n] = s;
printf("%d", f[n]);
return s;
}
int main()
{
int n;
scanf("%d", &n);
printf("%d\n", func(n));
return 0;
}