HDU

pro:给定一个蛋糕,一个矩阵房子,一只蚂蚁。最开始三者两两相离,问蚂蚁触摸到蛋糕后再触摸矩阵的最短距离。结果保留两位小数,坐标的绝对值<1e4;

sol:由于坐标不大,而且精度要求不高,不难想到可以暴力一点,直接分割圆。 假设分100000份,得到每个点到蚂蚁和矩阵的距离和,更新答案。 

(虽然我想到可能会三分这个圆,但是感觉情况蛮多的,因为可能不止一轮峰值,需要剥离三分的区间。

百度了下,情况其实不多。 因为剥离区间直接把圆分为[0,pi] [pi,2pi]即可。 因为如果有两个峰值,一定在对半的圆里。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=200010;
const double pi=acos(-1.0);
struct point{
    double x,y;
    point(){}
    point(double xx,double yy):x(xx),y(yy){}
};
struct seg{
    point a;
    point b;
};
point operator -(point a,point b){ return point(a.x-b.x,a.y-b.y);}
point operator +(point a,point b){ return point(a.x+b.x,a.y+b.y);}
double det(point a,point b){ return a.x*b.y-a.y*b.x;}
double dot(point a,point b){ return a.x*b.x+a.y*b.y;}
seg s[maxn]; point S,C,A,B;  double R;
double ptoseg(point P,point A,point B)
{
    point AP=P-A,BP=P-B;
    if(dot(B-A,AP)<=0) return sqrt(dot(AP,AP));
    if(dot(A-B,BP)<=0) return sqrt(dot(BP,BP));
    return fabs(det(AP,A-B))/sqrt(dot(A-B,A-B));
}
int main()
{
    while(~scanf("%lf%lf",&S.x,&S.y)){
        if(S.x==0&&S.y==0) return 0;
        scanf("%lf%lf%lf",&C.x,&C.y,&R);
        scanf("%lf%lf",&A.x,&A.y);
        scanf("%lf%lf",&B.x,&B.y);
        s[1].a=A; s[1].b=point(A.x,B.y);
        s[2].a=A; s[2].b=point(B.x,A.y);
        s[3].a=B; s[3].b=point(B.x,A.y);
        s[4].a=B; s[4].b=point(A.x,B.y);
        double ans=100000000;
        int T=100000; double t=pi*2/T;
        rep(i,1,T){
            point P;
            P.x=C.x+R*cos(t*i);
            P.y=C.y+R*sin(t*i);
            double tmp=sqrt(dot(P-S,P-S));
            double dis=ptoseg(P,s[1].a,s[1].b);
            rep(i,2,4) dis=min(dis,ptoseg(P,s[i].a,s[i].b));
            ans=min(ans,tmp+dis);
        }
        printf("%.2lf
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hua-dong/p/10683238.html