poj 2653 Pick-up sticks 线段相交

来源:互联网 发布:淘宝直通车一天烧50万 编辑:程序博客网 时间:2024/05/16 05:01


Pick-up sticks
Time Limit: 3000MS Memory Limit: 65536KTotal Submissions: 12518 Accepted: 4723

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

51 1 4 22 3 3 11 -2.0 8 41 4 8 23 3 6 -2.030 0 1 11 0 2 12 0 3 10

Sample Output

Top sticks: 2, 4, 5.Top sticks: 1, 2, 3.

Hint

Huge input,scanf is recommended.

Source

Waterloo local 2005.09.17


题意:有n(n<=100000)根针,现在依次丢到地上,给出阵的两端点坐标,问哪些针不被任何针压住?

题目保证答案<=1000


解:顺序放针,用一个容器维护最上面的阵,然后不断删去被压住的阵,假如新加的针。

(PS:并不能保证容器里的针<=1000)


判断线段相交:

</pre><pre name="code" class="cpp">bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)//规范相交{    double c1=Cross(b1-a1,a2-a1) ,c2=Cross(b2-a1,a2-a1);    double c3=Cross(a1-b1,b2-b1) ,c4=Cross(a2-b1,b2-b1);    return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;}



某个点相交都不算相交。

有线段a1a2,b1b2

c1*c2<0保证了b1、b2在a1a2两侧。

c3*c4<0保证了a1、a2在b1b2两侧,


如果某个值=0,证明有共线的情况。

排出了共线的情况。



/*   c++*/#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<set>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)#define mes(a,x,s)  memset(a,x,(s)*sizeof a[0])#define mem(a,x)  memset(a,x,sizeof a)#define ysk(x)  (1<<(x))typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn= 100000   ;const double eps=1e-10;int n;int dcmp(double x){    if(fabs(x)<eps)  return 0;    else return x<0?-1:1;}struct Point{    double x,y;    Point(double x=0,double y=0):x(x),y(y) {};    bool operator ==(const Point B)const {return dcmp(x-B.x)==0&&dcmp(y-B.y)==0;}    bool operator<(const Point& b)const    {        return dcmp(x-b.x)<0|| dcmp(x-b.x)==0 &&dcmp(y-b.y)<0;    }};typedef Point Vector;Vector operator -(Vector A,Vector B) {return Vector(A.x-B.x,A.y-B.y); }double Cross(Vector A,Vector B)//叉乘{    return A.x*B.y-A.y*B.x;}struct Line{    Point p,p2;    Vector v;    Line(){}    Line(Point a,Vector v):p(a),v(v){}//点线式    void twoPointIntial(Point p,Point p2)//两点式    {        this->p=p;        this->p2=p2;        v=  p2-p;    }}li[maxn+5];typedef Line Seg;bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)//规范相交{    double c1=Cross(b1-a1,a2-a1) ,c2=Cross(b2-a1,a2-a1);    double c3=Cross(a1-b1,b2-b1) ,c4=Cross(a2-b1,b2-b1);    return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;}set<int>se;void work(){    for(int i=1;i<=n;i++)    {        for(set<int>::iterator it=se.begin();it!=se.end();)        {            int j=*it;            set<int>::iterator it2=it;it2++;            if(SegmentProperIntersection(li[j].p,li[j].p2,li[i].p,li[i].p2   )) se.erase(it);            it=it2;        }        se.insert(i);    }    printf("Top sticks:");    int num=0;    for(set<int>::iterator it=se.begin();it!=se.end();it++)    {         if(num++)  printf(",");         printf(" %d",*it);    }    printf(".\n");}int main(){   std::ios::sync_with_stdio(false);   while(cin>>n&&n)   {       double x[2],y[2];       se.clear();       for1(i,n)       {           cin>>x[0]>>y[0]>>x[1]>>y[1];           li[i].twoPointIntial(Point(x[0],y[0]),Point(x[1],y[1]));       }       work();   }   return 0;}


0 0
原创粉丝点击