开始在实验室入手写的时候就在想会不会TLE,结果真的TLE
开始的想法是一边输入一边找木棍i可以覆盖的他前面的木棍j,如果他可以覆盖掉前面的那vis[i] = true, 开始我还天真的以为是O(N^2)的时间复杂度。可是这样是时间复杂度是 接近 O(N^3)的, 果断TLE了
那我们换一种思路, 当前木棍是I,我找它后面的可以覆盖它的木棍J,如果找到了就直接放弃它,找下一根木棍,如果没有那我就把它加到答案里面,这样的话最次才是o(n^2)
注意当两线段的交点是另一个线段的起点的时候,这种情况是不被覆盖的
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#define MAXN 111111
#define eps 1e-8
struct Point
{
double x, y;
Point () {};
Point (double a, double b)
{
x = a;
y = b;
}
};
struct Line
{
Point s, e;
Line() {};
Line(Point a, Point b)
{
s = a;
e = b;
}
} sta[MAXN];
int ans[MAXN];
double Across(Point a, Point b, Point c)
{
return (b.x - a.x) *(c.y - a.y) - (b.y - a.y) *(c.x - a.x);
}
int sig(double a)
{
if(a > eps)
return 1;
if(a < -eps)
return -1;
return 0;
}
bool segacross(Line a, Line b)
{
double s1,s2,s3,s4;
int d1 = sig(s1 = Across(a.s, a.e, b.s));
int d2 = sig(s2 = Across(a.s, a.e, b.e));
int d3 = sig(s3 = Across(b.s, b.e, a.s));
int d4 = sig(s4 = Across(b.s, b.e, a.e));
if(d1*d2 < 0 && d3*d4 < 0)
return true;
return false;
}
int main()
{
int n;
while(scanf("%d",&n) != EOF && n)
{
int cnt = 0;
double x1, y1,x2, y2 ;
for(int i = 0; i < n; i++)
{
scanf("%lf %lf %lf %lf",&x1, &y1, &x2, &y2);
sta[i] = Line(Point(x1,y1), Point(x2,y2));
}
for(int i = 0; i < n; i++)
{
bool flag = false;
for( int j = i+ 1; j < n; j++)
{
if(segacross(sta[j], sta[i]))
{
flag = true;
break;
}
}
if(!flag)
ans[cnt++] = i;
}
printf("Top sticks:");
for( int i = 0; i < cnt; i++)
printf(" %d%c",ans[i]+1,i == cnt-1? '.':',');
printf("\n");
}
}