POJ 2653 Pick-up sticks 枚举 + 判断两线段规范相交
有技巧的暴力过了

#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; #define eps 10e-8 #define inf 1<<29 struct point { double x, y; }; struct seg { point a, b; }s[100002]; bool vis[100003]; int ans[100003]; int n; double cross(point p0, point p1, point p2) { return (p1.x - p0.x)*(p2.y - p0.y) - (p1.y - p0.y)*(p2.x - p0.x); } bool line_cross(seg s1, seg s2)//判断两线段是否规范相交 { if(cross(s1.a, s1.b, s2.a)*cross(s1.a, s1.b, s2.b) > -eps || cross(s2.a, s2.b, s1.a)*cross(s2.a, s2.b, s1.b) > -eps )return 0; return 1; } int main() { int i, j; while(~scanf("%d",&n) && n) { for(i=1;i<=n;i++) scanf("%lf%lf%lf%lf", &s[i].a.x, &s[i].a.y, &s[i].b.x, &s[i].b.y); memset(vis, 0, sizeof(vis)); for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) if(line_cross(s[i], s[j])){vis[i]=1;break;}//用break就不会超时 printf("Top sticks: "); int num = 0 ; for(i=1;i<=n;i++) if(!vis[i]) ans[num++]=i; for(i=0;i<num-1;i++) printf("%d, ",ans[i]); printf("%d.\n",ans[i]); } return 0; }