#include<stdio.h> #include<math.h> const double eps=1e-8; int n; struct Point { double x,y; Point (){} Point (double _x,double _y) { x=_x; y=_y; } Point operator -(const Point &b)const { return Point (x-b.x,y-b.y); } double operator *(const Point &b)const { return x*b.x+y*b.y; } double operator ^(const Point &b)const{ return x*b.y-b.x*y; } }; struct Line { Point s,e; Line (){} Line (Point _s,Point _e) { s=_s; e=_e; } }; Line line [40]; double xmult(Point p0,Point p1,Point p2) { return (p1-p0)^(p2-p0); } bool seg_seg(Line l1,Line l2)//判断线段相交完全可以(不严格相交) { return xmult(l1.s,l2.s,l2.e)*xmult(l1.e,l2.s,l2.e)<=eps&&xmult(l2.s,l1.s,l1.e)*xmult(l2.e,l1.s,l1.e)<=eps; } Point point; int main() { double x1,x2,y1,y2; while(~scanf("%d",&n)) {for(int i=0;i<n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[i]=Line(Point(x1,y1),Point(x2,y2)); } line[n]=Line(Point(0,0),Point(0,100)); line[n+1]=Line(Point(100,0),Point(100,100)); scanf("%lf%lf",&x1,&y1); point =Point(x1,y1); int ans=0x3f3f3f,num; for(int i=0;i<n+2;i++) { num=0; for(int j=0;j<n;j++) { if(i==j) continue; if(seg_seg(Line(point,line[i].s),line[j])==true) num++; } //printf("%d ",num); if(ans>num) ans=num; num=0; for(int j=0;j<n;j++) { if(i==j) continue; if(seg_seg(Line(point,line[i].e),line[j])==true) num++; } //printf("%d ",num); if(ans>num) ans=num; } printf("Number of doors = %d ",ans+1); } }
题意:
在一个10X10的正方体中有着三十条以内的线段,线段的端点都在正方体的 边上,有一个宝物在正方体 的一个点上,求从正方体外到宝物处至少需要破坏几条直线来做门 ;
思路:
临界状态就是宝物与正方体四周的线段交点的连线与所有线段的相交的次数;
易错点:
1:枚举线段端点时,记得枚举正方形的四个顶点(还没理解为什么,---玄学)
2:枚举这条线段的端点时,不用判断这条线段是否与构造的线段相交。