博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
URAL 1348 求垂足
阅读量:4557 次
发布时间:2019-06-08

本文共 2675 字,大约阅读时间需要 8 分钟。

题意:

就是求点到线段的最短和最长距离。如果最短距离比L大,输出L - MIN 否则输出0。最长距离也是。

 

题解:

利用坐标旋转+向量的点积求投影向量从而得到垂足。这样做的精度远远高于解析几何方法,而且不用考虑任何边界情况~

ym applepi!!~

 

View Code
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 8 #define PI 3.14159265358979 9 #define EPS 1e-4 10 11 using namespace std; 12 13 struct PO 14 { 15 double x,y; 16 }; 17 18 struct LI 19 { 20 PO a,b; 21 }li[5]; 22 23 double len; 24 25 inline void read() 26 { 27 scanf("%lf%lf%lf%lf%lf%lf%lf",&li[1].a.x,&li[1].a.y,&li[1].b.x,&li[1].b.y,&li[2].a.x,&li[2].a.y,&len); 28 } 29 30 inline int doublecmp(double x) 31 { 32 if(x>EPS) return 1; 33 else if(x<-EPS) return -1; 34 return 0; 35 } 36 37 inline double dot(PO &a,PO &b,PO &c) 38 { 39 return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y); 40 } 41 42 inline double cross(PO &a,PO &b,PO &c) 43 { 44 return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); 45 } 46 47 inline double getlen(PO &a)//向量的模 48 { 49 return sqrt(a.x*a.x+a.y*a.y); 50 } 51 52 inline double getdis(PO &a,PO &b) 53 { 54 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 55 } 56 57 inline PO getty(PO b,PO a)//投影向量 58 { 59 PO res=a; 60 double k=dot(li[0].a,a,b)/(getlen(a)*getlen(a)); 61 res.x*=k; res.y*=k; 62 return res; 63 } 64 65 inline PO rotate(PO a,double hd)//旋转 66 { 67 PO c; 68 c.x=a.x*cos(hd)-a.y*sin(hd); 69 c.y=a.x*sin(hd)+a.y*cos(hd); 70 return c; 71 } 72 73 inline void go() 74 { 75 if(doublecmp(cross(li[1].a,li[1].b,li[2].a))==0)//在线段所在直线上 76 { 77 if(doublecmp(dot(li[2].a,li[1].a,li[1].b))<=0)//在线段上 78 { 79 puts("0.00"); 80 printf("%.2f\n",max(0.0,max(getdis(li[1].a,li[2].a),getdis(li[1].b,li[2].a))-len)); 81 } 82 else 83 { 84 double a=getdis(li[1].a,li[2].a)-len; 85 double b=getdis(li[1].b,li[2].a)-len; 86 if(a>b) swap(a,b); 87 printf("%.2f\n%.2f\n",max(a,0.0),max(b,0.0)); 88 } 89 } 90 else 91 { 92 li[2].b.x=li[1].b.x-li[1].a.x; 93 li[2].b.y=li[1].b.y-li[1].a.y; 94 li[2].b=rotate(li[2].b,-PI*0.5); 95 PO s=li[1].b; 96 s.x-=li[2].a.x; 97 s.y-=li[2].a.y; 98 PO ty=getty(s,li[2].b); 99 PO t;100 t.x=li[2].a.x+ty.x;101 t.y=li[2].a.y+ty.y;102 if(doublecmp(dot(t,li[1].a,li[1].b))<=0)//垂足在线段上 103 {104 printf("%.2lf\n",max(0.0,getlen(ty)-len));105 printf("%.2lf\n",max(0.0,max(getdis(li[1].a,li[2].a),getdis(li[1].b,li[2].a))-len));106 }107 else108 {109 double a=getdis(li[1].a,li[2].a)-len;110 double b=getdis(li[1].b,li[2].a)-len;111 if(a>b) swap(a,b);112 printf("%.2lf\n%.2lf\n",max(a,0.0),max(b,0.0));113 }114 }115 }116 117 int main()118 {119 read(),go();120 return 0;121 }

 

 

 

转载于:https://www.cnblogs.com/proverbs/archive/2013/02/24/2924729.html

你可能感兴趣的文章
有名管道的非阻塞设置
查看>>
Git使用教程-idea系列中git使用教程
查看>>
diff.js 列表对比算法 源码分析
查看>>
模块运用,文件搜索
查看>>
基于托管C++的增删改查及异步回调小程序
查看>>
hdu 1811 Rank of Tetris
查看>>
56. Merge Intervals 57. Insert Interval *HARD*
查看>>
java 调整jvm堆大小上限
查看>>
浏览器全屏之requestFullScreen全屏与F11全屏
查看>>
软件包管理:rpm命令管理-安装升级与卸载
查看>>
旋转图像
查看>>
字符串中的数字(字符串、循环)
查看>>
15.select into
查看>>
缓存-->Java中缓存的原理
查看>>
运行web项目端口占用问题
查看>>
Java Spring-IOC和DI
查看>>
【NOIP1999】【Luogu1015】回文数(高精度,模拟)
查看>>
Linux上安装Python3.5
查看>>
crt安装
查看>>
git切换分支报错:error: pathspec 'origin/XXX' did not match any file(s) known to git
查看>>