POJ 2653 线段相交

来源:互联网 发布:实时网络摄像头 编辑:程序博客网 时间:2024/04/29 18:10
这是一个计算几何的题目。题意是,按顺序给一系列的线段,问最终哪些线段处在顶端。
   只需要穷举判断,当前的线段会与哪些线段有交点即可。也就是暴力求解,但是线段数目N有10的5次方,平方算法是不能过的。这个题
能过的原因是题目描述里面说了,top的stick不会超过1000个。那么修改下暴力的方式题目就能过了。
   从小到大枚举每个棍子,判断它是否与后面的棍子相交,如果相交直接把当前棍子的top属性置为false,然后break内层循环。这样就不
会超时了,暴力也是需要技巧的,这句话说的很对啊。

   判断2条线段是否相交的算法直接按照黑书上的模板代码写了,那个模板代码还不错吧。。。

#include<cstdio>#include<cmath>#include<cstring>#include<queue>using namespace std;const int n_max=100005;const int m_max=1005;const double eps=1e-6;bool is_p[n_max];struct point{double x,y;void init(double tx,double ty){x=tx;y=ty;}};struct segment{point begin,end;void init(double x1,double y1,double x2,double y2){begin.init(x1,y1);end.init(x2,y2);}void pp(){printf("%.2lf %.2lf %.2lf %.2lf\n",begin.x,begin.y,end.x,end.y);}}seg[n_max];int dblcmp(double p){if(fabs(p)<eps){return 0;}return p>0?1:-1;}double det(double x1,double y1,double x2,double y2){return x1*y2 - x2*y1;}double cross(point a,point b,point c){return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);}bool segcross(segment s1,segment s2){return (dblcmp(cross(s1.begin,s2.begin,s2.end)) ^ dblcmp(cross(s1.end,s2.begin,s2.end))) == -2 &&(dblcmp(cross(s2.begin,s1.begin,s1.end)) ^ dblcmp(cross(s2.end,s1.begin,s1.end))) == -2;}int main(){int n;while(~scanf("%d",&n),n){memset(is_p,0,sizeof(is_p));double x1,y1,x2,y2;int i,j;for(i=1;i<=n;i++){scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);seg[i].init(x1,y1,x2,y2);}queue<int> q;for(i=1;i<=n;i++){bool b=true;for(j=i+1;j<=n;j++){if(segcross(seg[i],seg[j])){b=false;break;}}if(b){q.push(i);}}printf("Top sticks: ");while(q.size()>1){printf("%d, ",q.front());q.pop();}printf("%d.\n",q.front());q.pop();}return 0;}



原创粉丝点击