半数单集问题(set.cpp)

【问题描述】
给定一个自然数 n,由 n 开始可以依次产生半数集 set(n)中的数如下。n∈set(n);在 n 的
左边加上一个自然数,但该自然数不能超过最近添加的数的一半;按此规则进行处理,直到
不能再添加自然数为止。
例如,set(6)={6,16,26,126,36,136}。半数集 set(6)中有 6 个元素。
注意半数集不是多重集。集合中已经有的元素不再添加到集合中。
对于给定的自然数 n,编程计算半数集 set(n)中的元素个数。
【输入】
输入文件只有 1 行,给出整数 n。
【输出】
输出文件只有 1 行,给出半数集 set(n)中的元素个数。
【样例】
输入文件示例
set.in
6
【数据范围】
30%数据:1<=n<=20
100%数据:1<=n<=200
输出文件示例
set.out
6


 

这题很显然可以用递归来计数,但是我们会发现其实在递归过程中可能会重复,那么什么情况下才会重复呢?

当当前自然数/2后等于另外一个自然数/2和之后的,比如1224就可能由12<-24和1<-2<-24组成。

但是这种情况只在当前自然数大于10并且它的个位数大于等于它的十位数×2。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

#define il inline
#define ll long long
#define db double

using namespace std;

int ans=0;

il int count(int x)
{
  int s=0;
  if(!x)
    return 1;
  for(int i=0;i<=x/2;i++)
    {
      s+=count(i);
      if(i>10&&(2*(i/10))<=i%10)
	s-=count(i/10);
    }
  return s;
}

int main()
{
  freopen("set.in","r",stdin);
  freopen("set.out","w",stdout);
  int n;
  cin>>n;
  ans=count(n);
  printf("%d\n",ans);
  return 0;
}

 

转载于:https://www.cnblogs.com/gshdyjz/p/9870874.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值