Pick-up sticks(判断两直线相交)

Pick-up sticks

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 11335   Accepted: 4250

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 find the top sticks, that is these sticks such that there is no stick on top of them. Stan has noticed that the last thrown stick is always on top but he wants to know all the sticks that are on top. Stan sticks are very, very thin such that their thickness can be neglected.

Input

Input consists of a number of cases. The data for each case start with 1 <= n <= 100000, the number of sticks for this case. The following n lines contain four numbers each, these numbers are the planar coordinates of the endpoints of one stick. The sticks are listed in the order in which Stan has thrown them. You may assume that there are no more than 1000 top sticks. The input is ended by the case with n=0. This case should not be processed.

Output

For each input case, print one line of output listing the top sticks in the format given in the sample. The top sticks should be listed in order in which they were thrown. 
The picture to the right below illustrates the first case from input.

Sample Input

5
1 1 4 2
2 3 3 1
1 -2.0 8 4
1 4 8 2
3 3 6 -2.0
3
0 0 1 1
1 0 2 1
2 0 3 1
0

Sample Output

Top sticks: 2, 4, 5.
Top sticks: 1, 2, 3.题解:这个题是让找出与其他直线不交或者在其他直线最上面的直线;判断相交,两个直线的一个端点都要判断;代码:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define mem(x,y) memset(x,y,sizeof(x))
 7 using namespace std;
 8 typedef long long LL;
 9 const int INF=0x3f3f3f3f;
10 const int MAXN=100010<<1;
11 struct Point{
12     double x,y;
13     Point(double x=0,double y=0):x(x),y(y){}
14 };
15 typedef Point Vector;
16 Point dt[MAXN];
17 Vector operator - (Point a,Point b){return Vector(a.x-b.x,a.y-b.y);}
18 double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
19 int main(){
20     int n,k,j;
21     while(scanf("%d",&n),n){
22         k=0;
23         for(int i=1;i<=n;i++)
24             scanf("%lf%lf%lf%lf",&dt[i].x,&dt[i].y,&dt[i+n].x,&dt[i+n].y);
25             printf("Top sticks: ");
26         for(int i=1;i<n;i++){
27             for(j=i+1;j<=n;j++){
28                 if(Cross(dt[i]-dt[j],dt[i]-dt[j+n])*Cross(dt[i+n]-dt[j],dt[i+n]-dt[j+n])<=0)
29                     if(Cross(dt[j]-dt[i],dt[j]-dt[i+n])*Cross(dt[j+n]-dt[i],dt[j+n]-dt[i+n])<=0)
30                         break;
31             }
32             if(j==n+1)printf("%d, ",i);
33         }
34         printf("%d.\n",n);
35     }
36     return 0;
37 }
时间: 2024-10-25 00:35:05

Pick-up sticks(判断两直线相交)的相关文章

【POJ 1269】判断两直线相交

题 利用叉积解方程 #include <cstdio> #define MAX 1<<31 #define dd double int xmult(dd x1,dd y1,dd x2,dd y2,dd x,dd y){ return (x1-x)*(y2-y)-(x2-x)*(y1-y); } int main(){ int n; dd x1,y1,x2,y2,x3,y3,x4,y4; scanf("%d",&n); puts("INTERSE

You can Solve a Geometry Problem too (hdu1086)几何,判断两线段相交

You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6837 Accepted Submission(s): 3303 Problem Description Many geometry(几何)problems were designed in the ACM/ICPC. A

判断两直线是否平行

公式如下: 若直线A1x十+B1y+十C1=0与直线A2x十+2y+十C2=0平行,则: A1/A2=B1/B2≠C1/C2 ①若B1=B2=0,此时两直线斜率不存在,满足:A1/A1=B1/B2≠C1/;C2: ②若B1≠0.B2≠0,此时也满足A1/A2=B1/B2≠C1/C2 则两直线平行,有:A1/A2=B1/B2≠C1/C2 上代码: 1 /* 2 *函数名:if_not_parallel 3 *功能:两条直线不垂直的情况下,判断是否相交 4 *输入:(x1,y1),(x2,y2)是线

poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)

Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs of straws are

简单地判断判断两矩形相交/重叠 C#

最近需要用到矩形相交算法的简单应用,所以特地拿一个很简单的算法出来供新手参考,为什么说是给新手的参考呢因为这个算法效率并不是很高,但是这个算法只有简简单单的三行.程序使用了两种方法来判断是否重叠/相交,如果有兴趣可以看一下,如果觉得有bug可以留言.代码仅供参考. C#中矩形的方法为Rectangl(起始点坐标, 矩形的大小)或Rectangl(起始点x坐标, 起始点y坐标, 矩形宽, 矩形高),起始点为矩形区域的左上角. 方法一 姑且叫做“井字法”吧,延长其中一个矩形的四边使其形成一“井”字(

判断两直线是否相交 hdu1086

1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 struct line 7 { 8 double x1; 9 double y1; 10 double x2; 11 double y2; 12 }l[110]; 13 14 bool test(int i,int j) 15 { 16 int s=0; 17 double acd = (l[j].x1-l[i].x1)*(l[j].y1-l

判断两直线是否相交的叉积方法

struct point { double x,y; }; struct line { point a,b; }lines[110]; double chaji(point a,point b,point c,point d) { return (b.x-a.x)*(d.y-c.y)-(b.y-a.y)*(d.x-c.x); } bool isin(line l1,line l2) { if(chaji(l1.a,l2.a,l1.a,l1.b)*chaji(l1.a,l1.b,l1.a,l2.b

BNUOJ33566 Cycling Roads(并查集+判断两线段相交)

Cycling Roads Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on Ural. Original ID: 1966 64-bit integer IO format: %lld      Java class name: (Any) Prev Submit Status Statistics Discuss Next Font Size:  +   - Type:   None Graph T

判断两线段相交

#include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <stdlib.h> using namespace std; int n; struct point { double x; double y; }; struct v { point s; point e; } q[102]; int sum; double multi