hdu 1147 Pick-up sticks

来源:互联网 发布:开淘宝网 编辑:程序博客网 时间:2024/05/16 19:16

题目:

Pick-up sticks

Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Submit Status

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, t

hat 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

Sample Output

Top sticks: 2, 4, 5.

Top sticks: 1, 2, 3.

题目大意:

给n给线段,后面给的线段会压到前面放的线段,求最后放完所有线段在最上面未被压到的线段

题目思路:

1、每次去两个线段判断是否被相交,相交将前面的线段标记删除

2、用向量的

题目优化

1、如果简单的枚举可能会超时,所以需采用优化

2、被删除标记的就可以不再被查询

3、减少判断的次数,所以应从前往后判断 ,判断成立就退出

For(i=0...n-1)                      For(i=0...n-1)

for(j=i+1...n) for(j=i-1...0)

成立break   if(v[j])

  如果采用后面的 那么我们必然的多次的判断它是否被删除而空运行

如 号 被 号 压住 那么第一种只用3,:1 2, 1 3 , 1 4

而第二种   :1 2 , 1 3 , 1 4 , 1 5 , ......都要判断

程序:

 

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const double range=0.001;//误差bool v[100000];struct node//点{    double x,y;};struct wire//线{    node p;    node q;    friend bool operator < (wire wx,wire wy)    {        return wx.p.x>wy.p.x;    }} a[100010];int solve(int m,int n);int main(){    int n;    while(~scanf("%d",&n)&&n)    {        memset(v,0,sizeof(v));        for(int i=0; i<n; i++)            scanf("%lf %lf %lf %lf",&a[i].p.x,&a[i].p.y,&a[i].q.x,&a[i].q.y);        for(int i=0; i<n; i++)            for(int j=i+1; j<n; j++)//注意顺序                if(!v[j])                    if(solve(i,j))                    {                    v[i]=1;                    break;                    }        printf("Top sticks:");        for(int i=0,j=0; i<n; i++)            if(!v[i])                printf("%s %d",(j++?",":""),i+1);        printf(".\n");    }    return 0;}int solve(int m,int n){    node *p1=&a[m].p,*p2=&a[m].q,*q1=&a[n].p,*q2=&a[n].q;    if( min(p1->x,p2->x) <= max(q1->x,q2->x)+range &&            min(q1->x,q2->x) <= max(p1->x,p2->x)+range &&            min(p1->y,p2->y) <= max(q1->y,q2->y)+range &&            min(q1->y,q2->y) <= max(p1->y,p2->y)+range      )//排斥试验        if(            ((q1->x-p1->x)*(q1->y-q2->y)-(q1->y-p1->y)*( q1->x-q2->x)) * ((q1->x-p2->x)*(q1->y-q2->y)-(q1->y-p2->y)*(q1->x-q2->x)) <= range &&            ((p1->x-q1->x)*(p1->y-p2->y)-(p1->y-q1->y)*(p1->x-p2->x)) * ((p1->x-q2->x)*(p1->y-p2->y)-(p1->y-q2->y)*( p1->x-p2->x)) <= range        )//跨立实验            return true;    return false;}

 

0 0