卷包裹,线段相交,计算几何(找边界,LA 3218)
来源:互联网 发布:绝食知乎 编辑:程序博客网 时间:2024/05/17 06:58
成吨的细节。。。
就是找右转得最厉害的线段,然后沿着这个线段跑到最近的路口。
那如何找右转得最厉害的线段呢?就是枚举所有可能的下一个点,然后取其中最优的那个即可。
那如何判断哪个最优呢?
我是分类讨论
设上一个点是LAST,这一个点是NOW。
那么我目前的朝向就是V=NOW-LAST。
设两个点A,B。
如果A,B分别是左转和右转,那就选B。
否则如果A扭头,我就选B。
否则如果B扭头,我就选A。
否则如果B相对A右转,我就选B。
否则我选A。
那如何找最近的路口呢?就是枚举路上的所有路口,然后取其中最近的那个即可。
那如何判断最近呢?
直接两点间距离公式即可。
主要是难在很多琐碎的细节需要讨论清楚,否则就会找错方向和路口,从而出错或者陷入死循环。
debug浪费了非常多的时间,如果能完全想清楚再下手写代码就好了。
就是仅仅有大致思路是不够的,尽量把实现的细节都完全弄明白,具体到这个功能块每一步该怎么做,可以拿张纸写下具体过程,然后证明正确了再动手写代码。否则等到你写的时候就会比较无暇顾及细节,容易出错,而且没有那种对程序精细的掌控感。一旦出bug的话就会很不知所措,只能慢吞吞地单步调试。
再次通过自己带数据查出bug。这个方法真的很强.。但是这毕竟治标不治本。这方法不但速度有点慢,而且还得看运气。想办法提升自己的代码AC率才是提升自己的根本方法。既要学会使用技巧也要想办法提升自己。
代码
#include<bits/stdc++.h>using namespace std;struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y){} void Read() { scanf("%lf %lf",&x,&y); } bool operator < (const Point& rhs) const { return x<rhs.x||(x==rhs.x&&y<rhs.y); }};typedef Point Vector;const double eps = 1e-10;int dcmp(double x){ if(fabs(x)<eps) return 0; return x<0?-1:1;}Point operator + (Point A,Vector B){ return Point(A.x+B.x,A.y+B.y);}Vector operator - (Point A,Point B){ return Vector(A.x-B.x,A.y-B.y);}Vector operator * (Vector V,double t){ return Vector(V.x*t,V.y*t);}bool operator == (Point A,Point B){ return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0;}bool operator != (Point A,Point B){ return dcmp(A.x-B.x)!=0||dcmp(A.y-B.y)!=0;}double Dot(Vector A,Vector B){ return A.x*B.x+A.y*B.y;}double Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x;}double Len(Vector V){ return sqrt(Dot(V,V));}double Dist(Point A,Point B){ return Len(A-B);}Point GetIntersection(Point A,Point B,Point C,Point D){ Vector V1=B-A; Vector V2=D-C; Vector V3=C-A; double t=Cross(V3,V2)/Cross(V1,V2); return A+V1*t;}bool OnSegment(Point P,Point A,Point B){ Vector V1=A-P; Vector V2=B-P; return dcmp(Len(V1))==0||dcmp(Len(V2))==0||(dcmp(Cross(V1,V2))==0&&dcmp(Dot(V1,V2))<0);}bool SegmentIntersection(Point A,Point B,Point C,Point D){ if(dcmp(Cross(B-A,D-C))==0) return false; if(OnSegment(A,C,D)||OnSegment(B,C,D)||OnSegment(C,A,B)||OnSegment(D,A,B)) return true; Vector V1=C-A; Vector V2=D-A; Vector V3=A-C; Vector V4=B-C; return dcmp(Cross(B-A,V1))*dcmp(Cross(B-A,V2))<0&&dcmp(Cross(D-C,V3))*dcmp(Cross(D-C,V4))<0;}const int maxn = 110;int n;Point P[maxn];Point Poly[maxn*maxn];int cnt;Point s;Point last,now;bool cmp1(Point A,Point B){ return dcmp(Dist(last,A)-Dist(last,B))>0;}bool cmp2(Point A,Point B){ Vector V1=A-now; Vector V2=B-now; Vector V3=now-last; if(dcmp(Cross(V3,V1))*dcmp(Cross(V3,V2))<0) return dcmp(Cross(V3,V2))<0; else if(dcmp(Cross(V3,V2))==0&&dcmp(Dot(V3,V2))<0) return false; else if(dcmp(Cross(V3,V1))==0&&dcmp(Dot(V3,V1))<0) return true; return dcmp(Cross(V1,V2))<=0;}int main(){ while(~scanf("%d",&n)) { s=Point(200,200); for(int i=0;i<n;i++) { P[i].Read(); if(P[i]<s) s=P[i]; } last=s; last.x-=10; now=s; Point Next; cnt=0; while(1) { Poly[cnt++]=now; bool you=false; for(int i=0;i<n;i++) if(OnSegment(now,P[i],P[(i+1)%n])) { if(!OnSegment(P[i],now,last)&&(!you||cmp2(Next,P[i]))) Next=P[i],you=true; if(!OnSegment(P[(i+1)%n],now,last)&&(!you||cmp2(Next,P[(i+1)%n]))) Next=P[(i+1)%n],you=true; } for(int i=0;i<n;i++) if(SegmentIntersection(now,Next,P[i],P[(i+1)%n])) { Point Temp=GetIntersection(now,Next,P[i],P[(i+1)%n]); if(Temp!=now) Next=Temp; } if(Next==s) break; last=now; now=Next; } printf("%d\n",cnt); for(int i=0;i<cnt;i++) printf("%lf %lf\n",Poly[i].x,Poly[i].y); } return 0;}
0 0
- 卷包裹,线段相交,计算几何(找边界,LA 3218)
- 移动微小的距离,线段相交,计算几何(怪物陷阱,LA 2797)
- 【计算几何】线段相交
- POJ 1696 Space Ant(卷包裹 计算几何)
- 计算几何:线段相交(迷宫寻宝)
- 计算几何----判断线段相交(一)
- 计算几何---判断线段相交(二)
- poj 3565(计算几何,线段相交)
- 1264 线段相交(几何计算)
- 1264 线段相交(计算几何)
- nod1264 线段相交(计算几何)
- poj1039(计算几何)线段相交
- 【计算几何】判断线段相交
- 计算几何 线段相交 模板
- [Poj 1113] 计算几何之凸包(一){卷包裹算法}
- 计算几何之凸包_卷包裹算法
- POJ 3304 Segments(计算几何:直线与线段相交)
- poj 1269 Intersecting Lines(计算几何:线段相交)
- json请求数据有Unicode乱码
- 计算机视觉亮度与计算机视觉深度
- java设计模式之抽象工厂模式
- leetcode_middle_17_392. Is Subsequence
- codevs 最小乘车费用 1417
- 卷包裹,线段相交,计算几何(找边界,LA 3218)
- java学习记录----面向对象(二)
- 普及练习场之排序
- C语言蛇形矩阵例题
- 1034. Head of a Gang (30)
- [ACM] POJ 1753 Flip Game (枚举,BFS,位运算)
- 深度学习之Windows下安装caffe及配置Python和matlab接口
- Android Fragment 示例
- async-http 的封装