【计算几何】无线电测向【SGOI-2】…

本文介绍了无线电测向技术在计算几何中的应用,通过接收灯塔信号确定船只位置。编程任务是根据两个灯塔的信息计算船的位置,坐标系中包含角度和距离的计算。输入包含灯塔和船的数据,输出为船只的位置坐标。如果无法确定位置,则输出"NO ANSWER"。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

无线电测向【SGOI-2】

Time Limit:10000MS  Memory Limit:65536K
Total Submit:7 Accepted:2

Description

问题描述:
  一艘有天线定位装置的船能通过接收当地灯塔信号来确定自己的位置。每个灯塔固定在已知点上并发出特有的信号。当船检测到信号,它可通过旋转天线直到信号达到最大强度。这样就可确定自身与该灯塔的位置关系。只要接收到两个灯塔的信息,就有可能确定船当前的位置。
编程任务:
  通过一对灯塔信息来确定船的位置。
  灯塔和船的位置被确定在一个直角坐标系内。X轴正向指向东,Y轴正向指向北。船的航行路线从正北开始按顺时针用度表示。因此,北是0°,东是90°,南是180°,西是270°。灯塔与船的位置关系用相对于船的航行方向顺时针用度表示。

Input

数据输入:输入数据由文件名为INPUT.TXT的文本文件提供。文件的第一行是一个整数,表示灯塔的数目N(N<=30)。以下N行,每行表示一个灯塔,为灯塔名称(名称是20个以下的字母),X坐标和Y坐标。它们都用空格隔开。

  灯塔信息下面是船的信息包括三行,一行是船的方向,其余两行是所接收到的灯塔信号。
  具体如下:
  输入数据          数据的含义
  方向             船的航行方向;
  名称1 角度1       第一个灯塔信息的名称,灯塔的方位;
  名称2 角度2       第二个灯塔信息的名称,灯塔的方位。

  灯塔的方位为船与灯塔所在的直线与船的航行方向的夹角(从船的航行方向开始顺时针,角度1=角度1+180)。2个数据用空格隔开。

Output

数据输出:将船的位置(精确到2位小数)。输出到OUTPUT.TXT文件中。如果无法确定船的位置,应输出"NO ANSWER"(不能使用小写)。

Sample Input

2
a 51 60
b 153 79
30
a 210
b 160

Sample Output

160.83 123.41 

Source

 

点a坐标(ax,ay),点b坐标(bx,by),船p坐标(x,y)。

ap与x正半轴夹角ad,bp与x正半轴夹角bd。

 

三角函数得:

(y-ay)=tan(ad)*(x-ax)

(y-by)=tan(bd)*(x-bx)

得:

x=(by-ay+tan(ad)*ax-tan(bd)*bx)/(tan(ad)-tan(bd))

y=tan(ad)*(x-ax)+ay

 

pascal中没有tan函数,要用sin/cos,用弧度表示角,圆周率直接用pi,要注意tan(90)的情况

 

var

 ax,ay,bx,by:extended;

 n,d,ad,bd:longint;

 

procedure init;

var

 s,ns,sx,sy:string;

 i,j:longint;

 a:array[1..30+1,1..2]of string;

begin

 readln(n);

 for i:=1 to n do

  begin

  readln(a[i,1]);

  j:=pos(' ',a[i,1]);

  a[i,2]:=copy(a[i,1],1,j-1);

  delete(a[i,1],1,j);

  end;

 

 readln(d);

 readln(s);

 j:=pos(' ',s);

 ns:=copy(s,1,j-1);

 delete(s,1,j);

 

 for i:=1 to n do

  if ns=a[i,2] then

  begin

  j:=pos(' ',a[i,1]);

  sx:=copy(a[i,1],1,j-1);

  sy:=copy(a[i,1],j+1,length(a[i,1]));

  val(sx,ax);

  val(sy,ay);

  break;

  end;

 val(s,ad);

 ad:=ad mod 180;

 

 readln(s);

 j:=pos(' ',s);

 ns:=copy(s,1,j-1);

 delete(s,1,j);

 

 for i:=1 to n do

  if ns=a[i,2] then

  begin

  j:=pos(' ',a[i,1]);

  sx:=copy(a[i,1],1,j-1);

  sy:=copy(a[i,1],j+1,length(a[i,1]));

  val(sx,bx);

  val(sy,by);

  break;

  end;

 val(s,bd);

 bd:=bd mod 180;

end;

 

function tan(x:longint):extended;

var

 i,j:extended;

begin

 i:=(x/180)*pi;

 j:=sin(i)/cos(i);

 exit(j);

end;

 

procedure main;

var

 x,y:extended;

 i:longint;

begin

 ad:=ad+d;

 if ad<=90 then ad:=90-ad

           else ad:=270-ad;

 bd:=bd+d;

 if bd<=90 then bd:=90-bd

           else bd:=270-bd;

 

 if ad=bd then begin writeln('NO ANSWER'); exit; end;

 

 if ad=90 then

  begin

  x:=ax;

  y:=tan(bd)*(x-bx)+by;

  write(x:0:2,' ',y:0:2);

  end

  else

 if bd=90 then

  begin

  x:=bx;

  y:=tan(ad)*(x-ax)+ay;

  write(x:0:2,' ',y:0:2);

  end

  else

  begin

   x:=(by-ay+tan(ad)*ax-tan(bd)*bx)/(tan(ad)-tan(bd));

   y:=tan(bd)*(x-bx)+by;

   write(x:0:2,' ',y:0:2);

  end;

end;

 

begin

 init;

 main;

end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值