hdu4454 三分 求点到圆,然后在到矩形的最短路
矩形 然后 短路 三分
2023-09-11 14:14:00 时间
题意:
求点到圆,然后在到矩形的最短路.
思路:
求点到圆,然后在到矩形的最短路.
思路:
把圆切成两半,然后对于每一半这个答案都是凸性的,最后输出两半中小的那个就行了,其中有一点,就是求点到矩形的距离,点到矩形的距离就是点到矩形四条边距离中最小的哪一个,求的方法有很多,一开始想都没想直接敲了个三分(这样就是两重三分了)跑了890ms AC的,后来看了看人家的都是直接用模板过的,我也找了个模板,结果31ms AC,哎,没事真的多暂歇模板,只有好处没坏处是了..
#include<stdio.h> #include<math.h> #include<algorithm> #define eps 1e-3 double PI=acos(-1.0); using namespace std; typedef struct { double x ,y; }NODE; typedef struct { NODE A ,B; }EDGE; NODE node[10]; EDGE edge[10]; NODE S ,O; double diss1[10] ,diss2[10]; double R; bool camp(NODE a ,NODE b) { return a.x < b.x || a.x == b.x && a.y < b.y; } double dis(NODE a ,NODE b) { double tmp = pow(a.x - b.x ,2.0) + pow(a.y - b.y ,2.0); return sqrt(tmp); } double minn(double x ,double y) { return x < y ? x : y; } double abss(double x) { return x > 0 ? x : -x; } NODE getnode(double du) { NODE ans; ans.x = O.x + R *cos(du); ans.y = O.y + R * sin(du); return ans; } //********************************** struct Point { double x,y; Point(double xx=0,double yy=0):x(xx),y(yy){} Point operator -(const Point p1) { return Point(x-p1.x,y-p1.y); } double operator ^(const Point p1) { return x*p1.x+y*p1.y; } }; double cross(Point a,Point b) { return a.x*b.y-a.y*b.x; } inline int sign(double d) { if(d>eps)return 1; else if(d<-eps)return -1; else return 0; } double dis(Point A ,Point B) { return sqrt(pow(A.x - B.x ,2.0) + pow(A.y - B.y ,2.0)); } double ptoline(Point tp,Point st,Point ed)//求点到线段的距离 { double t1=dis(tp,st); double t2=dis(tp,ed); double ans=min(t1,t2); if(sign((ed-st)^(tp-st))>=0 && sign((st-ed)^(tp-ed))>=0)//锐角 { double h=fabs(cross(st-tp,ed-tp))/dis(st,ed); ans=min(ans,h); } return ans; } //************************ double search3_2(double L ,double R) { double low ,up ,mid ,mmid; NODE now; low = L ,up = R; while(1) { mid = (low + up) / 2; now = getnode(mid); Point A ,B ,C; A.x = now.x ,A.y = now.y; for(int i = 1 ;i <= 4 ;i ++) { B.x = edge[i].B.x ,B.y = edge[i].B.y; C.x = edge[i].A.x ,C.y = edge[i].A.y; diss1[i] = ptoline(A ,B ,C) + dis(S ,now); } sort(diss1 + 1 ,diss1 + 4 + 1); mmid = (mid + up) / 2; now = getnode(mmid); A.x = now.x ,A.y = now.y; for(int i = 1 ;i <= 4 ;i ++) { B.x = edge[i].B.x ,B.y = edge[i].B.y; C.x = edge[i].A.x ,C.y = edge[i].A.y; diss2[i] = ptoline(A ,B ,C) + dis(S ,now); } sort(diss2 + 1 ,diss2 + 4 + 1); if(diss1[1] > diss2[1]) low = mid; else up = mmid; if(abss(low - up) < eps) break; } return diss1[1]; } int main () { while(~scanf("%lf %lf" ,&S.x ,&S.y)) { if(S.x == 0 && S.y == 0) break; scanf("%lf %lf %lf" ,&O.x ,&O.y ,&R); scanf("%lf %lf %lf %lf" ,&node[1].x ,&node[1].y ,&node[2].x ,&node[2].y); node[3].x = node[1].x ,node[3].y = node[2].y; node[4].x = node[2].x ,node[4].y = node[1].y; sort(node + 1 ,node + 4 + 1 ,camp); edge[1].A.x = node[1].x ,edge[1].A.y = node[1].y; edge[1].B.x = node[2].x ,edge[1].B.y = node[2].y; edge[2].A.x = node[2].x ,edge[2].A.y = node[2].y; edge[2].B.x = node[4].x ,edge[2].B.y = node[4].y; edge[3].A.x = node[4].x ,edge[3].A.y = node[4].y; edge[3].B.x = node[3].x ,edge[3].B.y = node[3].y; edge[4].A.x = node[3].x ,edge[4].A.y = node[3].y; edge[4].B.x = node[1].x ,edge[4].B.y = node[1].y; printf("%.2lf\n" ,minn(search3_2(0 ,PI) ,search3_2(PI ,2*PI))); } return 0; }
相关文章
- Java实现 LeetCode 85 最大矩形
- Java实现 LeetCode 85 最大矩形
- java矩形的关系
- Java实现 蓝桥杯VIP基础练习 矩形面积交
- 【队列&栈】LeetCode 85. 最大矩形【困难】
- MFC Windows 程序设计[235]之写矩形和圆形DXF文件(附源码)
- Algorithm:C++语言实现之链表相关算法(单链公共结点问题、一般LCA、括号匹配、最长括号匹配、逆波兰表达式Reverse Polish Notation、直方图矩形面积、收集雨水问题)
- 蓝桥杯2019省赛——矩形切割改版的(Java实现)
- 【华为机试真题 Python实现】计算矩形面积【2022 Q2 |200分】
- 497. 返回随机非重叠矩形中的一个坐标点
- 【数字信号处理】序列傅里叶变换 ( 傅里叶变换实例 | 矩形窗函数 | 傅里叶变换 | 傅里叶变换幅频特性 | 傅里叶变换相频特性 )
- 150:vue+openlayers 多边形拐点用不同形状表示(圆形、三角形、矩形、正方形、星形...)
- 【OpenCV 例程300篇】211. 绘制垂直矩形