蜂窩小區最短距離實現 (極坐標+等差數列,十行代碼搞定)


題目描述:由正六邊形組成的蜂窩小區中,每個正六邊形的編號如圖所示。求任意2點間的距離。(規定最大編號不超過100000)

 

真的是Python十行代碼搞定,估計C++也是十幾行的代碼。分析題目,提煉數學模型,再寫代碼。


這個題可以不用各種復雜的算法,從數學角度解決。用數學思維簡化邏輯模型,而不是用計算機邏輯代替數學思維……
四大常用坐標系:笛卡爾直角坐標,極坐標,柱坐標,球坐標。這道題應該采用極坐標!加上等差數列!就夠了~

firstValue, secondValue為給的2點,Python代碼如下:

 1     n_fir = int(math.ceil((1+math.sqrt(1 + 4*(firstValue-1)/3))/2))
 2     n_sec = int(math.ceil((1+math.sqrt(1 + 4*(secondValue-1)/3))/2))
 3     if firstValue == 1:
 4         shortestPathLength = n_sec-1
 5     elif secondValue == 1:
 6         shortestPathLength = n_fir-1
 7     else:
 8         angle_fir = (n_fir*(n_fir-1)*3+1-firstValue)*2*math.pi/(6*(n_fir-1))
 9         angle_sec = (n_sec*(n_sec-1)*3+1-secondValue)*2*math.pi/(6*(n_sec-1))
10         shortestPathLength = round(math.sqrt((n_fir-1)**2+(n_sec-1)**2-2*(n_fir-1)*(n_sec-1)*math.cos(angle_fir-angle_sec)))
11     return int(shortestPathLength)

 

 

詳細解釋如下:

極坐標確定一個點,兩點之間的距離公式  

圖中可以用歸納法總結出等差數列:

圈號(等於極坐標軸長r-1) 容量 最小編號 最大編號
1 1(用0代替) 1(用0代替) 1(用0代替)
2 6(6*1) 2 7
3 12(6*2) 8 19
4 18(6*3) 20 37
5 24(6*4) 38 61

 

 

 

 

 

 

 

把第一圈的容量假設為0,最小最大編號假設為0,就是等差數列。(說明我們可以對含有編號1的特殊處理,其他的編號可以一起處理)

數字1、2、3、...、N-1、N,的隱含條件是:1)數字是有秩序(index)的,2)數字的秩序數(index)恰好等於該秩序處數字的值。

等差數列通項公式、求和公式

這里初值 a1 = 0, 公差d = 6

那么,Sn = ((圈號*(圈號-1))/2)*d + 1;  (最后加1是因為我們把a1=0了,實際編號從1開始的,所以這里加上)

 

給定編號怎么算位於第幾圈呢?

對求和公式整理得,n^2 -n -2*Sn/d = 0,把編號賦給Sn,解一元二次方程,因為△>0,所以有解:

 根據公式舍棄一個負根,剩下的一個正跟就是解n(一個小數),對n向上取整,就是該編號對應的圈號。

向上取整:把離散的圈號看成連續的,那么(2,3]區間是屬於第3圈。

極坐標定位:(設圈號為n, 已知點p)

 = n-1

 = ((n*(n-1)/2)*d + 1 - p)*π*/(d*(n-1)); π = 3.14...(圓周率),意思就是(第n圈的最大編號-給定的編號)*(圓周率/該圈的容量)!

所以,給定兩個點p1, p2,用求出距離,再四舍五入,就是任意2點間的距離!

四舍五入:連接任意兩個蜂窩的中心,會發現連線是對稱的。

最后,注意下,如果給定的2個點含有1,那么直接返回[另一個的圈號-1]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM