hdu 4619 Warm up 2

 
 
其实就是一个数学问题,给你一个圆柱的底面的圆心以及底面圆心的两个点,然后求出这个圆的的法向量和这个圆的半径,这样的话就会得到n个圆半径以及n条直线(包括方向向量和直线上一点),再求这些直线的距离看是否小于等于两条直线所在的两个圆的半径之和,如果存在任何一组小于等于的话,就输出Lucky,否则输出最小差距;
知道两条直线的法向量后,距离dis=|两条直线上两点的方向向量*(两条直线的方向向量的叉乘)| / |两条直线方向向量的模|
#include <cstdio>
#include <cmath>

double min(double x,double y)
{
    return x>y?y:x;
}
struct node
{
    double x,y,z;
    double r,s,t;
    double R;
};
node v[35];
void cal(double x1,double y1,double z1,double x2,double y2,double z2,int cur)
{
    v[cur].r=y1*z2-y2*z1;
    v[cur].s=z1*x2-z2*x1;
    v[cur].t=x1*y2-x2*y1;
    v[cur].R=sqrt(x1*x1+y1*y1+z1*z1);
}
double solve(int cur,int pos)
{
    double x,y,z;
    x=v[cur].x-v[pos].x;
    y=v[cur].y-v[pos].y;
    z=v[cur].z-v[pos].z;
    double r,s,t;
    r=v[cur].s*v[pos].t-v[cur].t*v[pos].s;
    s=v[cur].t*v[pos].r-v[cur].r*v[pos].t;
    t=v[cur].r*v[pos].s-v[cur].s*v[pos].r;
    return fabs(x*r+y*s+z*t)/sqrt(r*r+s*s+t*t);
}
int main()
{
    //freopen("in.txt","r",stdin);
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        double x1,y1,z1,x2,y2,z2;
        scanf("%d",&n);
        for(int i=0; i<n; ++i)
        {
            scanf("%lf%lf%lf",&v[i].x,&v[i].y,&v[i].z);
            scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&z1,&x2,&y2,&z2);
            cal(x1-v[i].x,y1-v[i].y,z1-v[i].z,x2-v[i].x,y2-v[i].y,z2-v[i].z,i);
        }
        double dis;
        int flag=-1;
        for(int i=0; i<n&&flag!=1; ++i)
            for(int j=i+1; j<n&&flag!=1; ++j)
            {
                double c;
                c=solve(i,j);
                if(c<=v[i].R+v[j].R) flag=1;
                if(flag==1) break;
                if(flag==-1) dis=c-(v[i].R+v[j].R),flag=0;
                else dis=min(dis,c-(v[i].R+v[j].R));
            }
        if(flag==1) puts("Lucky");
        else printf("%.2lf\n",dis);
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值