German Collegiate Programming Contest 2018​ - B. Battle Royale

Battle Royale games are the current trend in video games and Gamers Concealed Punching Circles (GCPC) is the most popular game of them all. The game takes place in an area that, for the sake of simplicity, can be thought of as a two-dimensional plane. Movement and positioning are a substantial part of the gameplay, but getting to a desired location can be dangerous. You are confident in your ability to handle the other players, however, while you are walking to your destination, there are two hazards posed by the game itself:

  • The game zone is bounded by a blue circle. Outside of this circle, there is a deadly force field that would instantly take you out of the game.
  • Inside the game zone, there is a red circle where you are exposed to artillery strikes. This circle is also too risky to enter.

You want to move from one spot on the map to another, but the direct path to your destination is blocked by the red circle, so you need to find a way around it. Can you find the shortest path that avoids all hazards by never leaving the blue or entering the red circle? Touching the boundaries of the circles is fine, as long as you do not cross them.

Input Format

The input consists of:

  • one line with two integers xc​, yc​ specifying your current location;
  • one line with two integers xd​, yd​ specifying your destination;
  • one line with three integers xb, yb, rb​​ specifying the center and radius of the blue circle;
  • one line with three integers xr​ ,yr​ , rr​ specifying the center and radius of the red circle.

All coordinates have an absolute value of at most 1000, and 1≤rb​,rr​≤1000. The red circle is strictly inside the blue circle. Your current location and destination are strictly inside the blue circle and strictly outside of the red circle, and the direct path between them is blocked by the red circle.

Output Format

Output the length of the shortest path that does not leave the blue or enter the red circle. The output must be accurate up to a relative or absolute error (whichever is lower) of 10 {^{-7}}.

 

解题思路:

首先注意红圈一定在蓝圈内,且一定挡在路线上。过一点做圆的切线有两条,两点共四个切点。同侧切点两两组合有两种方式,夹着两条不同的弧。在这种情况下,最短路为两点到圆的切线长和小弧长,三者之和。

问题转换为确定小弧长。这里有个很巧妙的方法,将起点、终点、圆心三者连成三角形,最小弧位于圆心所在顶角的开口一侧。最小弧所对圆心角也十分好求,余弦定理求出顶角后,减去两个夹角即可。

 

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef pair<double ,double> point;
#define x first
#define y second
point c,d,red,blue;
const double PI=acos(-1);
double r;
double ans;
void work()
{
   double cd=sqrt((c.x-d.x)*(c.x-d.x)+(c.y-d.y)*(c.y-d.y));
   double cr=sqrt((red.x-c.x)*(red.x-c.x)+(red.y-c.y)*(red.y-c.y));
   double dr=sqrt((red.x-d.x)*(red.x-d.x)+(red.y-d.y)*(red.y-d.y));
   double sita=acos((cr*cr+dr*dr-cd*cd)/(2*cr*dr));
   double d1=sqrt(cr*cr-r*r);
   double d2=sqrt(dr*dr-r*r);
   double l1=(2*PI-(acos(r/cr)+acos(r/dr)+sita))*r;
   double l2=(sita-(acos(r/cr)+acos(r/dr)))*r;
   ans=d1+d2+min(l1,l2);
}

int main()
{   
    cin>>c.x>>c.y>>d.x>>d.y>>blue.x>>blue.y>>r>>red.x>>red.y>>r;
    work();
    printf("%.10lf",ans);
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值