Pick-up sticks--poj2653(判断两线段是否相交)
http://poj.org/problem?id=2653
题目大意:有n根各种长度的棍 一同洒在地上 求在最上面的棍子有那几个
分析: 我刚开始想倒着遍历 因为n是100000 想着会超时吧 后来一看说 在上面的不会超过1000个 这就放心了 简单优化一下就过了
最后一个肯定是在最上面的 让后从他的下一个开始 每一个跟他相交的都是在他下面的 下一次就直接不循环他了
但是一直wa 彻底懵逼了
后来看了学长博客 他是正这循环 只要有跟他相交的就跳出 然后我就正这便利了一下 竟然过了 神奇ing !!!
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<ctype.h> #include<math.h> #include<algorithm> #include<iostream> using namespace std; #define N 100050 const double ESP = 1e-8; #define INF 0xffffffff int vis[N]; struct Point { double x,y; Point (double x=0,double y=0):x(x),y(y) {} Point operator - (const Point &temp)const { return Point(x-temp.x,y-temp.y); } bool operator == (const Point &temp)const { return (fabs(temp.x-x)<ESP && fabs(temp.y-y)<ESP); } int operator * (const Point &temp)const { double t=(x*temp.y)-(y*temp.x); if(t>ESP) return 1; if(fabs(t)<ESP) return 0; return -1; } }; struct node { Point A,B; node(Point A=0,Point B=0):A(A),B(B) {} }; node a[N]; Point p[N]; int s[N]; int main() { int n; while(scanf("%d",&n),n) { int b=0; double x1,x2,y1,y2; for(int i=1; i<=n; i++) { scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); p[b++]=Point(x1,y1); p[b++]=Point(x2,y2); a[i]=node(p[b-2],p[b-1]); } memset(vis,0,sizeof(vis)); memset(s,0,sizeof(s)); b=0; for(int i=1;i<=n;i++) { int flag=0; for(int j=i+1;j<=n;j++) { int k=abs((a[i].A-a[j].A)*(a[j].B-a[j].A)+(a[i].B-a[j].A)*(a[j].B-a[j].A)); int kk=abs((a[j].A-a[i].A)*(a[i].B-a[i].A)+(a[j].B-a[i].A)*(a[i].B-a[i].A)); if(kk==0 && k==0) { flag=1; break; } } if(flag==0) s[b++]=i; } printf("Top sticks: "); if(b==1) { printf("%d.\n",s[0]); continue; } for(int i=0; i<b-1; i++) { printf("%d, ",s[i]); } printf("%d.\n",s[b-1]); } return 0; }