POJ 2653 Pick-up sticks

POJ_2653

    这个题目有一个条件比较关键,就是“You may assume that there are no more than1000top sticks.”,这样如果我们边读入线段,便进行判断前面哪些被覆盖掉的话,会达到大约10^8左右的复杂度,而如果全部读完之后再逐一判断则是10^10的复杂度。

    这个题目没有明确说两个sticks在非规范相交的情况下算不算一个在另一个只上,看别人的题解说如果只有一个端点在另一条线段上,那么两个线段视作是不相互覆盖的,而且这个题也没有两条线段在一条直线上且部分重合的情况,所以我就偷懒了,只写了判断规范相交的代码。

#include<stdio.h>
#include<string.h>
#define MAXD 100010
#define zero 1e-8
int N, left[MAXD], right[MAXD];
double x1[MAXD], x2[MAXD], y1[MAXD], y2[MAXD];
double fabs(double x)
{
return x < 0 ? -x : x;
}
int dcmp(double x)
{
if(fabs(x) < zero)
return 0;
if(x < 0)
return -1;
return 1;
}
double det(double x1, double y1, double x2, double y2)
{
return x1 * y2 - x2 * y1;
}
double cross(int i, double x, double y)
{
return det(x - x1[i], y - y1[i], x2[i] - x1[i], y2[i] - y1[i]);
}
int check(int i, int j)
{
return dcmp(cross(i , x1[j], y1[j])) * dcmp(cross(i, x2[j], y2[j])) < 0 && dcmp(cross(j, x1[i], y1[i])) * dcmp(cross(j, x2[i], y2[i])) < 0;
}
void solve()
{
int i, j, k;
left[0] = right[0] = 0;
for(i = 1; i <= N; i ++)
{
scanf("%lf%lf%lf%lf", &x1[i], &y1[i], &x2[i], &y2[i]);
for(j = right[0]; j != 0; j = right[j])
if(check(i, j))
{
right[left[j]] = right[j];
left[right[j]] = left[j];
}
left[i] = left[0];
right[i] = 0;
right[left[0]] = i;
left[0] = i;
}
k = 0;
for(i = right[0]; i != 0; i = right[i])
++ k;
printf("Top sticks:");
j = 0;
for(i = right[0]; i != 0; i = right[i])
{
++ j;
if(j == k)
printf(" %d.\n", i);
else
printf(" %d,", i);
}
}
int main()
{
for(;;)
{
scanf("%d", &N);
if(!N)
break;
solve();
}
return 0;
}


你可能感兴趣的:(poj)