用编程枚举的方法,很容易计算得出可靠的结果:
各位数字之和是 81 的十位数有 48619 个。代码附后。
下面,用数学方法分析解答
分析各位数字之和的组合情况,过程会非常繁琐。
我们可以反过来思考:先将十位数都填作 9,即 9999999999。各位数字之和为 90,多了 90-81 = 9。
这样,就可以将问题转换为:从 9999999999 这个十位数上的各位上减去若干数,减去的总数为 9,有多少个方案?
用插板法:
9 个小球加 10 个,10+9 = 19 个,然后一字排开;
从 19 个小球的 18 个间隔中选择 9 个,插入隔板,将它们分成有序的 10 组;
再从每组拿掉一个小球,就得到组允许为 0、各组小球之和为 9 的分组方案。
18 选 9,C(18,9) = 18!/9!/(18-9)! = 48620 个方案。
这其中,9000000000 这一种情况要扣除。因为,十位正整数的首位不能为 0。
因此,一共有 48620-1 = 48619 个各位数字之和是 81 的十位数。
附:用于枚举的 Fortran 代码极其运行结果
! 各位数字之和是81的十位正整数有多少个?
! 2023-09-30
! szw_sh@163.com
integer a(10) ! 主程序
call cc(a,0,1) ! 调用递归枚举子程序
end
recursive subroutine cc(a,b,n) ! 递归枚举子程序
integer a(10),b
save m
data m/0/
do i=0,9 ! 循环枚举各个数字
if(n.eq.1.and.i.eq.0) cycle ! 首位不能是0,跳过
a(n)=i
k=b+i
if(k.gt.81) then ! 已选位数字之和大于81,退出递归
exit
else if(k+9-n*9.lt.0) then ! 未选择数字都为9仍小于81的,跳过
cycle
end if
if(n.eq.10) then ! 10位选完,数字之和等于81的,计数
if(k.ne.81) cycle
m=m+1
else ! 未满10位数字,继续递归
call cc(a,k,n+1)
end if
end do
if(n.eq.1) write(*,'(/a,i5)') 'total = ',m ! 输出总数
end