poj 2653 Pick-up sticks(判断线段相交)
题意:在桌上一次放n根木棒,求最上面的木棒编号;
思路:暴力枚举,看每根木棒上是否有木棒;
技巧:使用叉积,判断一个向量的两端点是否在另一向量的同侧,从而判断相交;
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const double epsi=1e-10; const int maxn=100005; inline int sign(const double &x){ if(x>epsi) return 1; if(x<-epsi) return -1; return 0; } struct point{ double x,y; point(){} point(double xx,double yy):x(xx),y(yy){} point operator -(const point &op2) const{ return point(x-op2.x,y-op2.y); } double operator ^(const point &op2) const{ return x*op2.y-y*op2.x; } }; inline double sqr(const double &x){ return x*x; } inline double mul(const point &p0,const point &p1,const point &p2){ return (p1-p0)^(p2-p1); } inline double dis2(const point &p1,const point &p2){ return sqr(p1.x-p2.x)+sqr(p1.y-p2.y); } inline double dis(const point &p0,const point &p1){ return sqrt(dis2(p0,p1)); } inline int cross(const point &p1,const point &p2,const point &p3,const point &p4) { double a1=mul(p1,p2,p3),a2=mul(p1,p2,p4); if(sign(a1)==0&&sign(a2)==0) return 2; //两向量共线 if(sign(a1)==sign(a2)) return 0; //两向量不相交 return 1; //两向量相交 } int n; point p1[maxn],p2[maxn]; int main() { int t,i,j,k; while(scanf("%d",&n)){ if(n==0) break; int f1=0; for(i=1;i<=n;i++) { scanf("%lf %lf %lf %lf",&p1[i].x,&p1[i].y,&p2[i].x,&p2[i].y); } printf("Top sticks:"); for(i=1;i<=n;i++) { int flag=0; for(j=i+1;j<=n;j++) { if(cross(p1[i],p2[i],p1[j],p2[j])&&cross(p1[j],p2[j],p1[i],p2[i]))//因为是线段,所以要相互判断 { flag=1;break; } } if(flag==0&&f1) printf(","); if(flag==0) printf(" %d",i),f1=1; } printf(".\n"); } return 0; }
有些梦想现在不去实现,以后就再也没机会了!!