POJ 2653 Pick-up sticks

来源:互联网 发布:怎样在淘宝买岛国片 编辑:程序博客网 时间:2024/05/19 23:01

简单的判断线段相交问题,用滚动数组记录最上面的线段,如果与当前的线段相交则抛弃,否则加入滚动数组。

#include<stdio.h>#include<iostream>using namespace std;double eps=1e-6;int n;struct Point{double x,y;};struct Line{Point s,e;};int que[2][100005];int top[2];Line stick[100005];double Mul(Point p1,Point p2,Point p)//pp1与pp2的叉积{return ((p1.x-p.x)*(p2.y-p.y)-(p2.x-p.x)*(p1.y-p.y));}bool iscross(Point p1,Point p2,Point p3,Point p4)//判断两条线段相交,先判断两条线段的范围符合{return ((max(p1.x,p2.x)-min(p3.x,p4.x)>-eps) && (min(p1.x,p2.x)-max(p3.x,p4.x)<eps) && (max(p1.y,p2.y)-min(p3.y,p4.y)>-eps) && (min(p1.y,p2.y)-max(p3.y,p4.y)<eps) && (Mul(p3,p2,p1)*Mul(p2,p4,p1)>-eps) && (Mul(p1,p4,p3)*Mul(p4,p2,p3)>-eps));}int main(){int t,i,j;while(scanf("%d",&n) && n){for(i=0;i<n;i++)scanf("%lf %lf %lf %lf",&stick[i].s.x,&stick[i].s.y,&stick[i].e.x,&stick[i].e.y);que[0][0]=0;top[0]=1;for(i=1;i<n;i++){top[i%2]=0;for(j=0;j<top[(i-1)%2];j++)//滚动数组只保存与当前加入的线段不想交的线段if(!iscross(stick[i].s,stick[i].e,stick[que[(i-1)%2][j]].s,stick[que[(i-1)%2][j]].e))que[i%2][top[i%2]++]=que[(i-1)%2][j];que[i%2][top[i%2]++]=i;}printf("Top sticks:");for(i=0;i<top[(n-1)%2]-1;i++)printf(" %d,",que[(n-1)%2][i]+1);printf(" %d.\n",que[(n-1)%2][i]+1);}return 0;}


原创粉丝点击