主题:求数字和(符合要求的回答都给30分)
jyf1987
[专家分:930] 发布于 2005-08-12 08:51:00
这里的数字和与数和是2码事
题目是这样的
输入一个数,求从1到该数的所有数的数字的和
例如:输入12
应该求1+2+3+4+5+6+7+8+9+1+0+1+1+1+2
一般的解决方案是把每个数拆开,然后慢慢算,但这种方法效率低,算到上千万时就要花点时间了,我想用数学方法总结规律来做,可是我的那个方法对于整百,整千,整万……的算不出来,只有各个数位都不为0时才可以算,不过速度超快,算几十万那么多时间,几十亿也是那么多时间
请各位大侠不吝赐教!!!!!!!!!!!!
30分啊,你不心动么?呵呵
回复列表 (共32个回复)
11 楼
jyf1987 [专家分:930] 发布于 2005-08-15 09:57:00
编程黑客的方法早就知道了,无非是他把里面那个循环换个形式而已
楼上的,我就是你说的这种思路
但是在设计算式的时候任意一个数位上有0就会出问题
12 楼
jyf1987 [专家分:930] 发布于 2005-08-15 10:48:00
我先把我的思路说说
从0算到9是45
从10算到19是10个1加0算到9就是1*10+45
同样的20到29就是2*10+45
那么从0算到99是0*10+45+1*10+45+2*10+45+……+9*10+45
所以是(0+1+2+……+9)*10+45*10=45*10+45*10
同样的从100到199比0到99多了100个1就是1*100+45*10+45*10
那么从0到999就是(0+1+2+……+9)*100+(45*10+45*10)*10=45*10^2+90*10^1
同里从0到9999就是45*10^3+90*10^2
从0到999……9(n个9)就是45*10^(n-1)+90*10^(n-2)
这就是我的研究思路
13 楼
zqnhlm [专家分:780] 发布于 2005-08-15 15:19:00
为什么你们喜欢求最优解啊!!!
14 楼
moz [专家分:37620] 发布于 2005-08-15 17:18:00
不是最优解
而是把代码优化一些,
加快一点速度,也就能扩大处理范围和计算能力
而这个“最”字,怕没几个人有那么大的胆子用得上。
而 jyf1987 ,你的思路我没多加研究,
也不能清楚的理解你是哪个地方没考虑详细
但思路归思路,毛主席说的,实践出真理
你不运行一下,怎么知道问题出在哪个地方,是哪个地方没完善呢?
有了思路,为什么不付诸实现的努力呢,
否则事情怎样去全面的看呢?
INPUT "", a&
j& = INT(LOG(a&) / LOG(10)) + 1
b$ = LTRIM$(STR$(a&))
IF j& <> LEN(b$) THEN
PRINT "计算数据出错,退出程序"
SYSTEM
END IF
FOR i& = 1 TO j&
o& = 10 ^ (i& - 1)
sum& = sum& + (a& \ o& \ 10&) * 45& * o&
m& = (a& \ o&) MOD 10
n& = m& - 1
sum& = sum& + ((1 + n&) * n& \ 2) * o&
sum& = sum& + m& * ((a& MOD o&) + 1)
NEXT
PRINT sum&
15 楼
Marlin [专家分:10] 发布于 2005-08-15 20:52:00
DIM jieguo(2000)
INPUT "n:"; n
FOR i = 1 TO n
b = i
FOR ii = 1 TO 2000
a = INT(b / 10 ^ (ii - 1))
jieguo(ii) = jieguo(ii) + a
b = b - 10 ^ (ii - 1) * a
NEXT
FOR ii = 1 TO 1999
IF jieguo(ii) > 9 THEN jieguo(ii) = jieguo(ii) - 10: jieguo(ii + 1) = jieguo(ii + 1) + 1
NEXT
NEXT
CLS
FOR i = 2000 TO 1 STEP -1
IF jieguo(i) > 0 THEN ii = i: i = 0
NEXT
FOR i = ii TO 1 STEP -1
PRINT jieguo(i);
NEXT
16 楼
编程黑客 [专家分:1660] 发布于 2005-08-15 21:26:00
因该是"她"
我是女生
漂亮的女生
我是女生
你不懂女生
[em4]
17 楼
moz [专家分:37620] 发布于 2005-08-16 01:27:00
太多冗余了,
把我自己写的东西再简化一下:
a&=99999
FOR i& = 1 TO (INT(LOG(a&) / LOG(10)) + 1)
o& = 10^(i&-1)
m& = (a&\o&) MOD 10
sum&=sum&+(a&\o&\10&)*45&*o&+((m&*(m&-1))\2)*o&+m&*((a& MOD o&)+1)
NEXT
PRINT sum&
18 楼
jyf1987 [专家分:930] 发布于 2005-08-16 09:25:00
我的思路其实就想找出个规律,不一步步去算而是根据各个数位上的数字去算
至于说实践嘛,就是实践时发现出问题了所以才来找你们啊
再说了,moz你干嘛不看看我的思路呢
19 楼
jyf1987 [专家分:930] 发布于 2005-08-16 09:28:00
还有,我看moz的代码里有log,我想知道你的计算方法
20 楼
moz [专家分:37620] 发布于 2005-08-16 11:41:00
你表达不清
我看不清楚你在说什么
比如说:
[color=FF0000]从10算到19是10个1加0算到9就是1*10+45[/color]
应该这样表达
[color=FF00FF]从10算到19是(10个1)+(0算到9的和)[/color]
同样的从100到199比0到99多了100个1就是1*100+45*10+45*10
[color=FF0000]那么从0到999就是(0+1+2+……+9)*100+(45*10+45*10)*10=45*10^2+90*10^1[/color]
这一句是不对的,
从0到999多出来的第三位数的和没错=(0+1+2+...+9)*100
但后面的就错了,(45*10+45*10)*10 <> 45*10^2+90*10^1
应该是 [color=FF00FF](45*10+45*10)*10 = 45*2*10^2[/color]
所以导致了后面的也错掉了
9999...999的累积数字和(n个9)应该是等于 45*n*10^(n-1) 才对
你都知道自己有了研究的思路了,但你连代码都不写出来给我看看,
假如你从来就没有写,那么我会说你连实践都没有,没有发言的权利.
如果你写了出来,只是想隐藏实力和炫耀的资本,那么我该说什么??
你的思路没有太多的错误,只是中间算错了数,但那也只是999的算法,
其他数字该怎么算你研究过了没有?
不全面的解决方案能做为答案吗?
log 的算式其实只是计算这个整数数值的位数的
用 len(str$(a&))-1 代替也是可以的
也就是说按每一位上的数字循环求和
比如说上面的134这个数值
(一). 个位上的(0到9)出现了多少次?
从0到12出现了13次 = 13 * (0+1+2+...+9) = 13 * 45 '第一位计算
高位数是13的时候 + (0+1+2+3+4) = 13*45+ f(4) = 595
f(x)代表数字x的累积和=1+2+3+....+x
(二). 十位上的(0到9)出现了多少次? '第二位第一步计算 A/C
百位上是0的时候出现了1次, 也就是 1*f(9)=45
但当十位数上的某个数字固定的时候,个位数上都可以有十次的变化,从0到9
也就是说在百位数上是0,十位数固定,还有个位数上的十次变化,
也就是 1* f(x) *10 = 450
当百位数是1的时候, 十位数上的0到3各出现一次, '第二位第二步计算 B/C
这个时候又得分开计算,
因为当十位数是0,1,2的时候,个位数都可以从0到9变化,也就是 f(2) * 10 = 30
'第二位第三步计算 C/C
最后当十位数是3的时候,个位数只可以从0到4变化,也就是 3 * 5 = 15
(三). 百位数怎么算? '第三位计算
是零的时候不用数,
只有1得算,1怎么算?
低位数上的变化只能从0到34变化只有35种变化=35*1
加起来 595 + 450 + 30 + 15 + 35 = 1125
明白了吗?
归结起来,某一位数字上的累积和应该有三步计算
abc, b是当前计算的单个位数,a是它高位的数值,是多位数
c是它低位的数值,是多位数
1. a * f(9) * 10 (10是b的位置)
2. f(b-1)*10
3. b * (c+1)
我来回复