傳送門:
問題描述
全球定位系統(gps)是乙個導航系統,根據一些在距地表大約20,000千公尺的軌道執行的衛星。每個衛星在乙個已知的軌道上執行,發射編碼著當前時間的無線電訊號。如果乙個裝有全球定位系統的交通工具有乙個非常精確的時鐘,它就可以比較它自己的當地時間和從衛星上接受到的編碼成訊號的時間。因為無線電訊號按乙個已知的速度傳播,所以這個交通工具能夠計算出它目前的位置和訊號發出時衛星的位置之間的距離。通過測算這個交通工具和一些在已知軌道上執行的衛星之間的距離,它可以非常精確地計算出自己的位置。
你必須寫乙個簡單的「自動導航裝置」程式,根據gps的導航。為了讓這個問題更簡單,我們描述乙個二維的問題。換句話說,你不需要考慮地球的曲率或者衛星的高度。此外,這個問題使用了更加適合於飛機和聲波的速度而不是衛星和無線電波。
給定一組移動的訊號源,你的程式必須計算出在笛卡爾平面內的接收點。然後,給定乙個在平面內的目標點,你的程式必須計算出從接收點到目標點指南針的指向。所有的指南針的指向用角度表示。指南針指向0(北)相當於y軸方向,指南針指向90(東)相當於x軸方向,就像圖1所展示的那樣。
輸入格式
讀入包含多組測試資料。
每組資料的第一行包含乙個整數n (1 ≤ n ≤ 10),表示訊號源的數量。接下來有3個浮點數:t,x和y。這裡,t表示當所有的訊號被接收時精確的當地時間,從基準時間(0時刻)按秒計時算起;x和y表示在笛卡爾平面內目標點的座標。接下來n行每行包含4個浮點數,攜帶有1個訊號源的資訊。前2個數字表示訊號源在基準時間在笛卡爾平面內的位置。第3個數字表示訊號源向指南針指向d(0 ≤ d < 360)前進。第4個數字是編碼在訊號裡的時間——也就是,訊號發出的時間,從基準時間按秒計時算起。輸入檔案所有數字小於10000,沒有乙個浮點數在小數點後超過5位。
最後一組資料的接下來一行包含4個0。
座標系的單位距離是1m。假設每個訊號源以100m/s的速度在笛卡爾平面上移動,訊號以350m/s的速度傳播。由於時鐘同步的不精確,你計算的距離都只精確到0.1m。也就是說,如果2個點相距0.1m以內,你應該把它們看成相同的點。訊號可能在傳播途中被干擾,所以接收到的多個訊號可能會矛盾。
輸出格式
對於每組資料,輸出資料的編號和從接收位置到目的地指南針的指向,用角度表示,四捨五入到整數。使用在樣例輸出中展示的標識。如果訊號包含不夠多的資訊來計算接收位置(也就是,符合所有訊號的超過乙個位置),輸出「inconclusive」。如果訊號矛盾(也就是,沒有位置符合所有的訊號),輸出「inconsistent」。如果接收位置相距目的地0.1m以內,輸出「arrived」。如果情形是inconclusive或者inconsistent,那麼你不需要考慮arrived的情形。
圖2對應著樣例的第乙個資料。t=0時3個衛星的位置a(-100,350),b(350,-100),和c(350,800)。被gps裝置接收的訊號都在t=1.75時被發出,當衛星處在位置a』,b』,c』的時候(然而,通常被gps裝置接收的訊號發出的時刻是不同的)。3個衛星發出訊號在t=2.53571時刻匯聚在d,意味著d是接收訊號的gps裝置的位置。從點d出發,指南針指向45度最終會到達目的地(1050,1050)。
很囉嗦的一道題……大致意思是這樣,各個衛星在某個時間會發出無線電波,一段時間後會被接收站接受,求解出接收站的位置。我們知道,波的邊界是圓形,這題本質就是讓我們求圓形的交。如果接收站正常的話,應該是位於所有圓的邊界上,也就是所有圓形的統一交點。這個題目的結果就是根據是否有交點,是否有唯一交點來分類的。如果有唯一交點,還需要求出目標點基於它的角度指向。
首先我們求出兩兩圓的交點並記錄(如果兩圓不相交,直接輸出inconsistent)。然後對每乙個交點,檢查它是否在所有的圓上,如果是,那麼它是我們的潛在接收站之一。然後判斷符合的這些點是否在誤差允許範圍內屬於同乙個點,如果沒有點的話是inconsistent,多個點的話就是inconclusive。
說實話這題的誤差範圍有點玄學,基本靠蒙,某個引數大了或者小了就容易全盤皆錯。而且題目中「如果2個點相距0.1m以內,你應該把它們看成相同的點」有點讓人蛋疼,不禁想到如果是很多個點相差0.1m,是否該看成同乙個點。我後來是讓點集合的直徑不超過0.1m算作相同,反正對了就算了。
另外如果是n=1,需要直接特判掉。
總得來說,思想很簡單,但是花了我不少時間,因為有不少細節和特殊情況要考慮。
#include
#include
#include
#include
using
namespace std;
typedef
long
double db;
typedef complex point;
typedef point vector;
const db pi=
acosl(-
1);struct circle
point point
(db a);}
}o[12];
db l,u,v,px,py,deg,sta,ed,vx,vy,t;
int n,kase,cn,an;
point res[2]
,c[305
],ans[
305]
,f;db ang
(vector v)
intdcmp
(db x)
intgetcirclecircleintersection
(circle c1, circle c2)if(
dcmp
(c1.r+c2.r-d)
<0)
return0;
if(dcmp
(abs
(c1.r-c2.r)
-d)>0)
return0;
db a=
ang(c2.c-c1.c)
; db da=
acosl
((c1.r*c1.r+d*d-c2.r*c2.r)/(
2*c1.r*d));
res[0]
=c1.
point
(a-da)
,res[1]
=c1.
point
(a+da);if
(dcmp
(abs
(res[0]
-res[1]
))==0
)return1;
return2;
}bool
oncircle
(point x, circle c)
intmain()
,(ed-sta)
*350};
}bool incos=
false
; cn=0;
for(
int i=
1,t;i
!incos;i++
)for
(int j=i+
1;j<=n&&
!incos;j++)}
an=0;
for(
int i=
1,p;i<=cn;i++
)printf
("trial %d: "
,++kase);if
(incos||an==
0&&n>1)
puts
("inconsistent");
else;if
(abs
(f-ans[1]
)<
0.1l
)puts
("arrived");
else
printf
("%d degrees\n",(
int)(90
-ang
(f-ans[1]
)/pi*
180+
0.5));
}}}return0;
}
計算幾何 圓與圓的交點座標
給出兩圓的圓心座標和半徑,求出兩圓交點的座標 如下圖 可根據餘弦定理求出角a的大小,再根據函式atan2 可求出向量c1c2的方位角t 這樣一來,我們所求的交點就是以圓心c1.c為起點,大小為c1.r 角度為 t a 和 t a 的兩個向量 include include includeusing ...
計算幾何之圓與圓的交點
計算圓與圓的交點,需要用到餘弦定理 步驟如下 求出兩個圓的圓心距d 求出向量c2.c c1.c與c1.c到某交點的向量夾角a 求出向量c2.c c1.c與x軸的夾角t 那麼,兩個交點就分別是以c1.c為起點,大小為c1.r,角度為t a t a的兩個向量 題目 cgl 7 e ac include ...
計算幾何之求圓與直線的交點
求圓與直線的交點的方法是 求圓心c在直線l上的投影點pr 求出直線l上的單位向量e 根據r和pr的長度來計算出圓內線段部分的一半base 用pr base e即得到答案 題目 cgl 7 d ac include include include using namespace std define ...