欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

HDU 2773 White Water Rafting 【数学+点到线段的最短距离】

程序员文章站 2022-04-01 15:51:16
...


传送门:HDU2773


White Water Rafting
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description
You have been hired by a big theme park to design a new attraction: a white water rafting ride. You already designed the track; it is a round trip that is described by an inner and an outer polygon. The space in between the two polygons is the track.
You still need to design the rafts, however. It has been decided that they should be circular, so that they can spin freely along the track and increase the fun and excitement of the ride. Besides that, they should be as big as possible to fit the maximum number of people, but they can’t be too big, for otherwise they would get stuck somewhere on the track.
What is the maximum radius of the rafts so that they can complete the track?

Input
On the first line one positive number: the number of testcases, at most 100. After that per testcase:
*One line with an integer ni (3 ≤ ni ≤ 100): the number of points of the inner polygon.
*ni lines with two integers each: the coordinates of the points of the inner polygon in consecutive order.
*One line with an integer no (3 ≤ no ≤ 100): the number of points of the outer polygon.
*no lines with two integers each: the coordinates of the points of the outer polygon in consecutive order.
All coordinates have absolute value no larger than 1000. The points of the polygons can be given in either clockwise or counterclockwise order and the two polygons do not intersect or touch themselves or each other. The outer polygon encloses the inner polygon.

Output
Per testcase:
*One line with a floating point number: the maximal radius of the white water rafts. This number must have a relative or absolute error less than 10-6.

Sample Input
2
4
-5 -5
5 -5
5 5
-5 5
4
-10 -10
-10 10
10 10
10 -10
3
0 0
1 0
1 1
5
3 -3
3 3
-4 2
-1 -1
-2 -2

Sample Output
2.5
0.70710678




题解:
是个水题。就是求出内环上所有点到外环边的最短距离,最大半径就是最小的最短距离的一半。
(其实还要遍历一遍外环上的点到内环边的最短距离)。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
struct Node
{
  int x,y;
};
double D(Node a,Node b,Node p)//计算点到线段最短距离
{
  double ap=(b.x-a.x)*(p.x-a.x)+(b.y-a.y)*(p.y-a.y);
  if(ap<=0) return sqrt((p.x-a.x)*(p.x-a.x)+(p.y-a.y)*(p.y-a.y));//最短为ap
  double ab=(b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y);
  if(ap>=ab) return sqrt((p.x-b.x)*(p.x-b.x)+(p.y-b.y)*(p.y-b.y));//最短为bp
  double r=ap/ab;
  double px=a.x+(b.x-a.x)*r;
  double py=a.y+(b.y-a.y)*r;
  return sqrt((p.x-px)*(p.x-px)+(p.y-py)*(p.y-py));//垂线距离
}
Node inner[110],outer[110];
int t,ni,no;
int main()
{
  scanf("%d",&t);
  while(t--)
  {
    scanf("%d",&ni);
    for(int i=0;i<ni;i++)
    {
      scanf("%d%d",&inner[i].x,&inner[i].y);
    }
    scanf("%d",&no);
    for(int i=0;i<no;i++)
    {
      scanf("%d%d",&outer[i].x,&outer[i].y);
    }
    double maxn=inf;
    for(int i=0;i<no-1;i++)
    {
      for(int j=0;j<ni;j++)
      {
        double d=D(outer[i],outer[i+1],inner[j]);
        maxn=min(maxn,d);
      }
    }
    for(int i=0;i<ni;i++)
    {
      double d=D(outer[no-1],outer[0],inner[i]);
      maxn=min(maxn,d);
    }
    printf("%.8f\n",maxn/2);
  }
  return 0;
}