[ACM ] 217
※ 引述《glob (TOEFL&GRE GOGOGO)》之銘言:
: 想法:
: 因為船的航行角度是從北方(0度)開始計算,順時針方向為正
: 給一方向角 a, 速度v
: 令船的航線 斜率的兩個分量為(sin(a),cos(a))
: 假設船座標(x,y)
: 對於t1時間的 beacon 1 (beacon1.x, beacon1.y), 其相對船航行角度 angle 1
: 我可以找出船的位置和 beacon連線的直線方程式 =>
: y - beacon1.y = cot(a + angle 1)*(x-beacon1.x); --------- 1)
: 經過 t2-t1 時間:
: 船走到了 (x',y') = (x+v*sin(a)(t2-t1), y+v*cos(a)*(t2-t1) )
: 對於t2時間的 beacon 2 (beacon2.x, beacon2.y), angle 2
: y'- beacon2.y = cot(a + angle 2)*(x'-beacon2.x); ------- 2)
: 把 1) 2)聯立得解 請問這樣的想法對嗎? 囧>>>
: 感謝回答 = =""
囧 找不出錯來... 請問有大大可以幫我看看 code嗎? 實在是頭大..Orz..
一些地方寫了註解 感謝 ==...
題目:http://acm.uva.es/p/v2/217.html
有一個有向天線接收器的船可以透過燈塔確定它自身的位置。
每一個燈塔的位置都是已知的,並且向一個固定的方向發射信號。
當一艘船檢測到信號的時候,它旋轉天線接收器的直到信號的強度最大。
這樣我們就得到了一個相對于某個燈塔的角度。
給定兩次利用燈塔得到的訊息(時間、相對角度、燈塔位置),
通常我們可以確定船的絕對位置。
我們已知的數值是︰船行駛的方向和速度、燈塔的位置、
還有就是兩次利用燈塔所得到的訊息,注意天線不能判別燈塔是在哪個方向,
如果讀到的相對角度是90 degs,那可能燈塔在90度或者是270度的角度上。
#include <iostream>
#include <stdlib.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include <iomanip>
using namespace std;
// (name,x,y):=beacon(x,y)
string name[31];
double x[31], y[31];
// a:=course, v:=velocity
double a,v;
// index:= num of beacon, deal:=num of data
// t1,b1:= time of beacon1, index of beacon1
// t2,b2:= time of beacon2, index of beacon2
int index, deal,t1,t2,b1,b2;
// m1,m2:= slope of line1, slope of line2
// k1,k2:= distance of movement in x_axis and y_axis between (t2-t1)
// x_v,y_v:= final position of ship
// a1,a2:= angle1, angle 2
double m1,m2,k1,k2,a1,a2,x_v,y_v;
bool bx,by;
int Scenario=1;
double d2,d1;
void fail()
{
cout<<"Scenario "<<Scenario<<" : "<<"Position cannot be
determined"<<endl;
Scenario++;
}
void succeed()
{
cout<<"Scenario "<<Scenario<<" : "<<"Position is ";
printf("(%.2lf, %.2lf)\n",x_v,y_v);
Scenario++;
}
void reset()
{
k1=v*sin(2*acos(0.)*a/180)*(t2-t1);
k2=v*cos(2*acos(0.)*a/180)*(t2-t1);
x_v=0.,y_v=0.;
d1=a+a1;
d2=a+a2;
//將d1,d2的範圍調整到[0,360)
while(d1>=360.){d1-=360.;}
while(d2>=360.){d2-=360.;}
bx=false,by=false;
}
/*檢查兩直線是否平行,若平行則無解 */
bool cross()
{
if(abs(d1-d2)==0. || abs(d1-d2)==180.)
return true;
else
return false;
}
/*計算第 1條直線方程式*/
void test1()
{
if(d1==90.||d1==270.){
y_v=y[b1];
by=true;
}else if(d1==0. ||d1==180.){
x_v=x[b1];
bx=true;
}else
m1=cos(2*acos(0.)*d1/180.)/sin(2*acos(0.)*d1/180.);
}
/*計算第 2條直線方程式*/
void test2()
{
if(d2==90.||d2==270.){
y_v=y[b2];
if(bx==true) x_v+=k1;
else
x_v = (y_v-k2-y[b1])/m1+x[b1] +k1;
}else if(d2==0.||d2==180.){
x_v=x[b2];
if(by==true)
y_v+=k2;
else
y_v=m1*(x_v-k1-x[b1])+y[b1]+k2;
}else{
m2=cos(2*acos(0.)*d2/180.)/sin(2*acos(0.)*d2/180.);
if(bx==true){
x_v+=k1;
y_v=m2*(x_v-x[b2])+y[b2];
}else if(by==true){
y_v+=k2;
x_v =(y_v-y[b2])/m2+x[b2];
}else{
x_v =(m2*x[b2]-m1*k1-m1*x[b1]+k2+y[b1]-y[b2])/(m2-m1);
y_v = m2*(x_v-x[b2])+y[b2];
}
}
succeed();
}
void cal()
{
reset();
if(cross())
{
fail();
}else{
test1();
test2();
}
}
void find(string s,int *a)
{
int i=1;
while( name[i].compare(s) != 0 ){i++;}
*a = i;
}
void read()
{
for(int i=1;i<=index;i++){ cin>>name[i]>>x[i]>>y[i]; }
cin>>deal;
for(int i=1;i<=deal;i++){
string bea1,bea2;
cin>>a>>v;
cin>>t1>>bea1>>a1;
cin>>t2>>bea2>>a2;
find(bea1,&b1);
find(bea2,&b2);
cal();
}
}
int main(int argc, char *argv[])
{
while((cin>>index)){ read(); }
system("PAUSE");
return 0;
}
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.230.176.168
※ 編輯: glob 來自: 61.230.176.168 (04/28 22:54)
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.230.176.168
※ 編輯: glob 來自: 61.230.176.168 (04/28 23:12)
Prob_Solve 近期熱門文章
PTT數位生活區 即時熱門文章