poj 2653 线段相交

题意:一堆线段依次放在桌子上,上面的线段会压住下面的线段,求找出没被压住的线段。

sol:从下向上找,如果发现上面的线段与下面的相交,说明被压住了。break掉

其实这是个n^2的算法,但是题目已经说了没被压住的线段不超过1000个,所以不会爆

  1   #include<math.h>
  2   #include <stdio.h>
  3   #include <string.h>
  4
  5   bool ans[100100];
  6   int n;
  7   double X1,X2,Y1,Y2;
  8
  9   #define eps 1e-8
 10   #define PI acos(-1.0)//3.14159265358979323846
 11   //判断一个数是否为0,是则返回true,否则返回false
 12   #define zero(x)(((x)>0?(x):-(x))<eps)
 13   //返回一个数的符号,正数返回1,负数返回2,否则返回0
 14   #define _sign(x)((x)>eps?1:((x)<-eps?2:0))
 15
 16   struct point
 17   {
 18       double x,y;
 19       point(){}
 20       point(double xx,double yy):x(xx),y(yy)
 21       {}
 22   };
 23
 24   struct line
 25   {
 26       point a,b;
 27       line(){}      //默认构造函数
 28       line(point ax,point bx):a(ax),b(bx)
 29       {}
 30   }l[100100];
 31
 32   //求矢量[p0,p1],[p0,p2]的叉积  //p0是顶点
 33   //若结果等于0,则这三点共线  //若结果大于0,则p0p2在p0p1的逆时针方向  //若结果小于0,则p0p2在p0p1的顺时针方向
 34   double xmult(point p1,point p2,point p0)
 35   {
 36       return(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
 37   }
 38   //计算dotproduct(P1-P0).(P2-P0)
 39   double dmult(point p1,point p2,point p0)
 40   {
 41       return(p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
 42   }
 43   //两点距离
 44   double distance(point p1,point p2)
 45   {
 46       return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
 47   }
 48   //判三点共线
 49   int dots_inline(point p1,point p2,point p3)
 50   {
 51       return zero(xmult(p1,p2,p3));
 52   }
 53   //判点是否在线段上,包括端点
 54   int dot_online_in(point p,line l)
 55   {
 56       return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;
 57   }
 58   //判点是否在线段上,不包括端点
 59   int dot_online_ex(point p,line l)
 60   {
 61       return dot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y));
 62   }
 63   //判两点在线段同侧,点在线段上返回0
 64   int same_side(point p1,point p2,line l)
 65   {
 66       return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
 67   }
 68     //判两线段相交,包括端点和部分重合
 69   int intersect_in(line u,line v)
 70   {
 71       if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
 72           return!same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
 73       return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);
 74   }
 75
 76 int main()
 77 {
 78     while (scanf("%d",&n))
 79     {
 80     if (n==0)   break;
 81     memset(ans,false,sizeof(ans));
 82     for (int i=1;i<=n;i++)
 83     {
 84         //cin>>X1>>Y1>>X2>>Y2;
 85         scanf("%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2);
 86         l[i]=line(point(X1,Y1),point(X2,Y2));
 87         ans[i]=true;
 88     }
 89
 90     for (int i=1;i<=n-1;i++)
 91     {
 92         int j=i+1;
 93         while (j<=n)
 94         {
 95             line l1=l[i],l2=l[j];
 96             if (intersect_in(l1,l2)!=0)
 97             {
 98                 ans[i]=false;
 99                 break;
100             }
101             j++;
102         }
103     }
104     //Top sticks: 2, 4, 5.
105     int ANS[1010];
106     int nm=0;
107     for (int i=1;i<=n;i++)
108         if (ans[i])
109         {
110             nm++;
111             ANS[nm]=i;
112         }
113     printf("Top sticks: ");
114     for (int i=1;i<nm;i++)
115         printf("%d, ",ANS[i]);
116     printf("%d.\n",ANS[nm]);
117     }
118     return 0;
119 }
时间: 2024-08-02 06:59:19

poj 2653 线段相交的相关文章

Pick-up sticks - POJ 2653 (线段相交)

题目大意:有一个木棒,按照顺序摆放,求出去上面没有被别的木棍压着的木棍..... 分析:可以维护一个队列,如果木棍没有被压着就入队列,如果判断被压着,就让那个压着的出队列,最后把这个木棍放进队列,不过速度并不快,枚举才是最快的......据说是任意时刻没有超过1000个top sticks.....很难注意到. 代码如下: =======================================================================================

poj 2653 线段与线段相交

Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 11884   Accepted: 4499 Description Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to fin

poj 1410 线段相交判断

http://poj.org/problem?id=1410 Intersection Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11329   Accepted: 2978 Description You are to write a program that has to decide whether a given line segment intersects a given rectangle. An ex

poj 1066 线段相交

链接:http://poj.org/problem?id=1066 Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5431   Accepted: 2246 Description Archeologists from the Antiquities and Curios Museum (ACM) have flown to Egypt to examine the great pyramid

POJ 2653 线段交

思路: 运用队列存储没有被覆盖的木棍,没加入一个棍子,就要判断一下是否队列中的棍子被覆盖,如果被覆盖,就从队列中删除: 线段交判断方法:跨立实验 Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9698 Accepted: 3591 Description Stan has n sticks of various length. He throws them one at a time on th

poj 1269 线段相交/平行

模板题 注意原题中说的线段其实要当成没有端点的直线.被坑了= = 1 #include <cmath> 2 #include <cstdio> 3 #include <iostream> 4 #include <cstring> 5 using namespace std; 6 7 #define eps 1e-8 8 #define PI acos(-1.0)//3.14159265358979323846 9 //判断一个数是否为0,是则返回true,否

Pipe - POJ 1039(线段相交交点)

题目大意:有一个不反光并且不透光的管道,现在有一束光线从最左端进入,问能达到的最右端是多少,输出x坐标. 分析:刚开始做是直接枚举两个点然后和管道进行相交查询,不过这样做需要考虑的太多,细节不容易掌控.后来发现其实只需要对接口进行一下相交查询就简单多了,因为只需要考虑能不能通过每个截口就可以了,而且这样做的好处还有没有平行线和重叠线的情况,因为所有的截口都是垂直于x轴的,换一种想法海阔太空啊. 代码如下: =============================================

The Doors - POJ 1556 (线段相交)

题目大意:有一个房间(左上角(0,10),右下角(10,0)),然后房间里有N面墙,每面墙上都有两个门,求出来从初始点(0,5),到达终点(10,5)的最短距离. 分析:很明显根据两点之间直线最短,所以所走的路线一定是点之间的连线,只需要判断一下这两点间知否有墙即可. 代码如下: =============================================================================================================

POJ 2074 | 线段相交

#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define eps 1e-8 using namespace std; bool dcmp(double x,double y) { if (fabs(x-y)>eps) return 1; return 0; } struct point { double x,y; point () {}; point (