【題目】已知某次通話的開始時間,線束時間,怎樣計算通話時長?(假設通話不會超過24小時,但有可能跨午夜)
比如: 12:40:15 到 12:41:18 通話 63秒,而23:59:57 到 00:00:01 僅通話了4秒。
這個問題與【問題39】有個共同的小竅門:欲求 a, b 的差,可以找乙個原點 x
,問題變成:
a −b
=(a−
x)−(
b−x)
a-b= (a-x)-(b-x)
a−b=(a
−x)−
(b−x
)顯然,選午夜時刻即 0:0:0 是最便於計算的。
以下 haskell 碼:
-----通話時長
duration :: (
int,
int,
int)
->
(int
,int
,int)-
>
intduration (h1,m1,s1)
(h2,m2,s2)
=(delta (h2,m2,s2)
- delta (h1,m1,s1)
+ dayseconds)
`mod` dayseconds
where
dayseconds =24*
60*60 delta (h, m, s)=60
*60* h +
60* m + s
main :: io (
)main =
doprint $ duration (19,
28,17)
(19,29
,4)print $ duration (23,
59,58)
(0,3
,12)
其中, (a - b + a) % a 這種演算法是很常用的處理技巧。這是害怕 a 比 b 小時產生負值。那麼 a 比 b 大呢? 那就白加了唄,反正最後還取模的,加多少個 a 都不妨。
mod
加了反引號,當中綴運算子用,比其字首形式更具可讀性。但要注意,此運算子的優先順序是可以單獨定義的。haskell 把它定義的比 + - 更高優先。
這個對基點求差的思路很具有普遍意義。很多問題中能用上。
有個著名的最大連續和問題
,求 乙個給定的整數序列中(有正有負),其所有子串行(連續一段)和的最大值。這不用對所有的位置組合 [a,b] 求和,只要算出從開始到每個位置的和,再利用 [a,
b]=s
uma−
sumb
[a,b] = sum_a - sum_b
[a,b]=
suma
−su
mb 即可。
haskell 基礎題解(06)
題目 如果乙個數的所有真因子 不包含它自身的因子 之和恰等於其自身,則該數為完全數,也稱為完美數 perfect number 完全數有許多奇妙的性質。但它們很稀少,你來求前幾個吧。最小的乙個是 6,因為 6 1 2 3 這個完全數的定義已經很清楚了,如果沒有什麼妙法,就地毯式搜尋也可以。下法就是 ...
haskell 基礎題解(07)
題目 11 1 1 2 1 1 3 3 1 1 4 6 4 1 這個陣勢叫楊輝三角,國外叫帕斯卡三角。前一行的數字中,每兩個相鄰的數字相加就得到下一行的數字。左右兩邊的數永遠是 1 寫個程式,輸出前幾行的楊輝三角。import data.list intersperse yang hui int y...
haskell基礎題解(14)
題目 用自然數蛇形填充乙個 n 階的方陣。當n 5時,形如 這個問題用 haskell 解決時與 題目13 差別甚微。實際上,從函式式的思考習慣看,只要讓有些行作成後反轉一下就可以了。上 ju n f x x 0.n 1 where f row even row take n row n 1.odd...