【洛谷】数的计算(多种思路仅自己学习)

我们要求找出具有下列性质数的个数(包括输入的自然数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;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值