zoj 2551 || poj 2653 Pick-up sticks

按顺序扔出来一些棍子,求最后那些棍子在上面。
按照顺序,如果后面的线段和前面的线段相交了,那前面线段肯定不可能在最上面。
开始TLE死了。。。><。。。查了半天错,还优化了,最后发现是数组少加了个0><。。我了个去啊。。
改过后,优化的方法A掉了。看DISCUSS,有人说,从前往后找,比较省时间,我改了改,居然也A掉了><。。。就是 如果前面那棍子与后面棍子一交叉,就break了。
注意,端点相连 不算交叉情况><。。
我的优化是队列哈,如果没被覆盖掉,就入队,然后下一个棍子判断它和队列里的是否交叉,如果不交叉,入队,这点需要小判断一下,如果和它判断的点已经出队完毕,下面就不能再判了,要不就无限出队入队了。。
队列版
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> using namespace std; const double eps = 1e-6; const int MAX = 100010; struct point{ double x,y; }; struct line{ point a,b; }; line l[MAX]; bool dy(double x,double y) { return x > y + eps;} // x > y bool xy(double x,double y) { return x < y - eps;} // x < y bool dyd(double x,double y) { return x > y - eps;} // x >= y bool xyd(double x,double y) { return x < y + eps;} // x <= y bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 { return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y); } bool onSegment(point a, point b, point c) { double maxx = max(a.x,b.x); double maxy = max(a.y,b.y); double minx = min(a.x,b.x); double miny = min(a.y,b.y); if( dyd(c.x,minx) && xyd(c.x,maxx) && dyd(c.y,miny) && xyd(c.y,maxy) ) return true; return false; } bool segIntersect(point p1,point p2, point p3, point p4) { double d1 = crossProduct(p3,p4,p1); double d2 = crossProduct(p3,p4,p2); double d3 = crossProduct(p1,p2,p3); double d4 = crossProduct(p1,p2,p4); if( xy(d1 * d2,0.0) && xy( d3*d4,0.0 ) ) return true; return false; } int tmp[100010]; queue<int> q; int main() { int n; while( ~scanf("%d",&n) && n ) { for(int i=0; i<n; i++) scanf("%lf %lf %lf %lf",&l[i].a.x,&l[i].a.y,&l[i].b.x ,&l[i].b.y); q.push(0); for(int i=1; i<n; i++) { int ind = -1; while( !q.empty() ) { int t = q.front(); line curl = l[t]; q.pop(); if( !segIntersect(l[i].a,l[i].b,curl.a,curl.b) ) { if( ind == -1 ) ind = t; q.push(t); } if( q.empty() || q.front() == ind ) break; } q.push(i); } printf("Top sticks:"); while( !q.empty() ) { int ans = q.front(); q.pop(); if( !q.empty() ) printf(" %d,",ans+1); else printf(" %d./n",ans+1); } } return 0; }
小内存版。。。
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> using namespace std; const double eps = 1e-6; struct point{ double x,y; }; struct line{ point a,b; int ind; }; bool dy(double x,double y) { return x > y + eps;} // x > y bool xy(double x,double y) { return x < y - eps;} // x < y bool dyd(double x,double y) { return x > y - eps;} // x >= y bool xyd(double x,double y) { return x < y + eps;} // x <= y bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 { return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y); } bool onSegment(point a, point b, point c) { double maxx = max(a.x,b.x); double maxy = max(a.y,b.y); double minx = min(a.x,b.x); double miny = min(a.y,b.y); if( dyd(c.x,minx) && xyd(c.x,maxx) && dyd(c.y,miny) && xyd(c.y,maxy) ) return true; return false; } bool segIntersect(point p1,point p2, point p3, point p4) { double d1 = crossProduct(p3,p4,p1); double d2 = crossProduct(p3,p4,p2); double d3 = crossProduct(p1,p2,p3); double d4 = crossProduct(p1,p2,p4); if( xy(d1 * d2,0.0) && xy( d3*d4,0.0 ) ) return true; return false; } queue<line> q; line l; int main() { int n; while( ~scanf("%d",&n) && n ) { scanf("%lf %lf %lf %lf",&l.a.x,&l.a.y,&l.b.x ,&l.b.y); l.ind = 0; q.push(l); for(int i=1; i<n; i++) { scanf("%lf %lf %lf %lf",&l.a.x,&l.a.y,&l.b.x ,&l.b.y); l.ind = i; int m = 0; int ind = -1; while( !q.empty() ) { line curl = q.front(); q.pop(); if( !segIntersect(l.a,l.b,curl.a,curl.b) ) { if( ind == -1 ) ind = curl.ind; q.push(curl); } if( q.empty() || q.front().ind == ind ) break; } q.push(l); } printf("Top sticks:"); while( !q.empty() ) { line ans = q.front(); q.pop(); if( !q.empty() ) printf(" %d,",ans.ind+1); else printf(" %d./n",ans.ind+1); } } return 0; }
普通版。。。求的顺序变了下,所以木有TLE
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> using namespace std; const double eps = 1e-6; const int MAX = 100010; struct point{ double x,y; }; struct line{ point a,b; }; line l[MAX]; bool top[MAX]; bool dy(double x,double y) { return x > y + eps;} // x > y bool xy(double x,double y) { return x < y - eps;} // x < y bool dyd(double x,double y) { return x > y - eps;} // x >= y bool xyd(double x,double y) { return x < y + eps;} // x <= y bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 { return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y); } bool onSegment(point a, point b, point c) { double maxx = max(a.x,b.x); double maxy = max(a.y,b.y); double minx = min(a.x,b.x); double miny = min(a.y,b.y); if( dd(crossProduct(a,b,c),0.0) && dyd(c.x,minx) && xyd(c.x,maxx) && dyd(c.y,miny) && xyd(c.y,maxy) ) return true; return false; } bool segIntersect(point p1,point p2, point p3, point p4) { double d1 = crossProduct(p3,p4,p1); double d2 = crossProduct(p3,p4,p2); double d3 = crossProduct(p1,p2,p3); double d4 = crossProduct(p1,p2,p4); if( xy(d1 * d2,0.0) && xy( d3*d4,0.0 ) ) return true; if( dd(d1,0.0) && onSegment(p3,p4,p1) ) return true; if( dd(d2,0.0) && onSegment(p3,p4,p2) ) return true; if( dd(d3,0.0) && onSegment(p1,p2,p3) ) return true; if( dd(d4,0.0) && onSegment(p1,p2,p4) ) return true; return false; } int out[1010]; int main() { int n; while( ~scanf("%d",&n) && n ) { memset(top,true,sizeof(top)); for(int i=0; i<n; i++) scanf("%lf %lf %lf %lf",&l[i].a.x,&l[i].a.y,&l[i].b.x ,&l[i].b.y); for(int i=0; i<n; i++) for(int k=i+1; k<n; k++) if( top[i] && segIntersect(l[i].a,l[i].b,l[k].a,l[k].b) ) { top[i] = false; break; } int count = 0; for(int i=0; i<n; i++) if( top[i] ) out[count++] = i+1; printf("Top sticks:"); for(int i=0; i<count-1; i++) printf(" %d,",out[i]); printf(" %d./n",out[count-1]); } return 0; }  

你可能感兴趣的:(zoj 2551 || poj 2653 Pick-up sticks)