※ 引述《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)