問題起源於一個簡單的算法題:已知三點求最小多邊形面積(不會超過100邊形)。
步驟以下:算法
重點在第三步,圓心角用弧度表示都是小數,初等數學裏小數沒有最大公約數的概念。可是這道題目網上都有這個步驟,算法仍然基於展轉相除法,可是會自定義一個浮點相等的函數,以下:函數
def feq(x, y): return fabs(x - y) < 1e-2 def _fgcd(x, y): if feq(x, 0): return y if feq(y, 0): return x return _fgcd(y, x%y)
其中feq函數判斷兩數相等的規則是兩者差值的絕對值小於0.01, 使用這個精度代碼就能夠accept,使用1e-6這個高精度代碼就會WA,然而這個精度設置的理由在哪裏?測試
我寫了一段測試代碼,測試不一樣精度對結果的影響(有部分是多餘的,懶的改了):code
def feq(x, y, e): return fabs(x - y) < e def fgcd(iters, e): def _fgcd(x, y): if feq(x, 0, e): return y if feq(y, 0, e): return x return _fgcd(y, x%y) return reduce(_fgcd, iters) def main(): a = [1.23456, 6.54321] for i in range(1,7): e = 10 ** (-i) print e, fgcd(a,e)
獲得的結果是:get
0.1 0.12333 0.01 0.12333 0.001 0.12333 0.0001 0.000120000002036 1e-05 2.99999969435e-05 1e-06 2.99999969435e-05
能夠發現,不一樣精度的選擇對於結果的影響很是大。咱們能夠觀察到最大公約數的fgcd的結果必定是大於精度e的。
這也是易於理解的,比精度小的值就被認爲是0了,而0是不能成爲公約數的。數學
問題到這裏彷佛有點眉目,咱們回顧一下題目,爲何精度必定要是0.01呢?
彷佛有一個條件咱們一直沒有用到——不會超過100邊形,看到這裏你可能就明白了。
弧度越小,邊數越多,而題目指明瞭邊數不會超過100,於是咱們能夠求得一個弧度的最小值:2π/100。這個值近似於0.06283185307179587,也就是說咱們求得最大公約角度不會小於0.06,可是若是咱們比較精度設置得小於0.01,那麼極有可能會獲得小於0.06的最大公約角,所以網上答案大部分設置爲0.01。it
細心的網友會想,比較精度設置爲0.01獲得的結果仍然有可能小於0.06啊,是否是你理解的根本不對呢?
爲了驗證個人想法,我把比較精度設置爲0.06,再次提交答案,仍然accept,可是把比較精度設置爲0.07就WA了。gc
比較精度設置爲0.01仍然經過檢測,我認爲是數據集自身的緣由,它自己沒有那些特別不湊巧的小數,使用0.01和0.06能夠獲得相同的結果。數據
這個只是我本身的理解,也許根本也就不對,若是你有更好的看法,歡迎及時評論。
問題的原題在:http://codeforces.com/problemset/problem/1/C, 你們能夠試一下。co