一道數學題,怎麼計算是最快速的?

Q:如果小明一天按照當天日期數給付小強一筆費用(如:一月一日,11元,五月二十一日,521元,如此類推)那麼小強一年(按照閏年計算)可獲得多少元?


身為小學奧數老師,就用小學奧數的思維解答一下吧-。-

每一天的費用由當天的月和日共同組成,計算的時候分開算比較簡單吧。。。

先算日:

不論哪一天,日所提供的錢數都是日這個數本身。例如今天5.22,那麼二十二日決定了522元中的22元,8.31中三十一日決定了831元中的31元。全年中29天的月份有1個,30天的月份有4個,31天的月份有7個。那麼全年中日所提供的錢數應為:

left( 1+2+cdotcdotcdot +29 
ight) +left(  1+2+cdotcdotcdot+30 
ight)	imes 4+left( 1+2+cdotcdotcdot+31 
ight) 	imes 7

也就是left(  1+2+cdotcdotcdot+30 
ight)	imes 12+31	imes 7-30=5767


再算月:

每個月前9天的日是一位數,那麼月所提供的錢數是月	imes 10,從第10天開始日是兩位數,那麼月所提供的錢數是月	imes 100

一月中月所提供的總錢數為:1	imes 9	imes 10+1	imes 22	imes 100=1	imes 31	imes 100-1	imes 9	imes 90

同理,二月為:2	imes 29	imes 100-2	imes 9	imes 90

……

十二月為:12	imes 31	imes 100-12	imes 9	imes 90

總錢數為:left[  left( 1+2+cdotcdotcdot +12 
ight)	imes 30+1-2+3+5+7+8+10+12 
ight]	imes 100- left( 1+2+cdotcdotcdot +12 
ight)	imes 9	imes 90

=238400-63180=175220


那麼全年總計應為5767+175220=180987


或許編個程算會比較快吧= = 只是提供一種用紙筆計算的思路。。

粗略一算也許有錯也許有更好的演算法╮(╯▽╰)╭

最後吐槽一下,知乎這個公式編輯器真是太特么的難用了。。。 (╯°Д°)╯︵ ┻━┻


看到樓上 @Zhong Robert 給了 Mathematica 的方案,但是太長,其實一行就夠了:

ToExpression @ StringJoin @ (ToString /@ DatePlus[{2004, 1, 1}, #][[2 ;; 3]]) /@ Range[366] // Total

這裡選 2004 年是因為 2004 年是個閏年

截個圖

評論中 曹洪(at不到抱歉)提供了更短的:

Sum[FromDigits@StringJoin[ToString/@Rest@DatePlus[{2004,1,1},i]],{i,366}]


人生苦短,我用python

sum([int((date(2000, 1, 1) + timedelta(x)).strftime("%m%d")) for x in range(366)])


給個Excel數組公式的角度

=SUMPRODUCT(--TEXT("2011/12/31"+ROW(1:366),"md"))


提供一個R代碼
library(data.table)
dd&<-seq(as.IDate("2016-1-1"),as.IDate("2016-12-31"),by="1 day")
sum(as.numeric(paste(month(dd),mday(dd),sep="")))
結果是180987


將時間格式強制轉化為int再求和。。。


寫了一段很醜陋的代碼:
m1 = {1, 3, 5, 7, 8, 10, 12};
m2 = {4, 6, 9, 11};
m3 = {2};
d1 = Range[1, 31];
d2 = Range[1, 30];
d3 = Range[1, 28];

list1 = Tuples[{m1, d1}];
list1 = IntegerDigits /@ list1;
list1 = Flatten /@ list1;
list1 = FromDigits /@ list1;

list2 = Tuples[{m2, d2}];
list2 = IntegerDigits /@ list2;
list2 = Flatten /@ list2;
list2 = FromDigits /@ list2;

list3 = Tuples[{m3, d3}];
list3 = IntegerDigits /@ list3;
list3 = Flatten /@ list3;
list3 = FromDigits /@ list3;


Total[list1] + Total[list2] + Total[list3]

運行結果是:180758

這裡把2月當成了28天,如果閏年則再加上229就好了。

修改了一下代碼,不知道是更好了,還是更難看懂了:

Total[Join[
FromDigits /@
Map[Flatten,
Map[IntegerDigits,
Tuples[{{1, 3, 5, 7, 8, 10, 12}, Range[1, 31]}]]],
FromDigits /@
Map[Flatten,
Map[IntegerDigits, Tuples[{{4, 6, 9, 11}, Range[1, 30]}]]]
, FromDigits /@
Map[Flatten, Map[IntegerDigits, Tuples[{{2}, Range[1, 28]}]]]]]


Haskell version:
需要先

import Data.Time.Calendar.MonthDay

print $ sum $ map ((x,y) -&> read (show x ++ show y) :: Int) $ map (dayOfYearToMonthAndDay True) [1..366]


用vb算:
dim i as date
dim s as long
dim j as long
s=0
i="1999/12/31"
for j=1 to 366
s=s+val(format(i+j,"mmdd"))
next
for j=1 to 12
s=s-810*j
next
msgbox s


讓我慢慢算算…


(1+2+。。+9)*12 + (1+2+。。+12)*10*9 這是12個月1號到9號的錢
+(10+11+。。+30)*12 + (1+2+。。+12)*100 * 21這是12個月10號到30號的錢
+31*7+(1+3+5+7+8+10+12)*100 這是7個31號的錢
- 230-229 如果閏年減一個,否則減兩個。


11~19
110~131
21~29
210~229
30~39
310~331
……
91~99
910~930
101~109
1010~1031
111~119
1110~1130
121~129
1210~1231

總結一下,就是11~129然後減去20、30、40~110、120
然後110~130~~~~1210~1230(131、-230、331、531、731、831、1031、1231)
這樣看起來,不論怎麼算,都簡單明了~~


推薦閱讀:

如何評價清華附中校長王殿軍叫停女兒奧數?

TAG:數學 | 代數 | 應用數學 | 趣味數學 | 奧林匹克數學 |