对线段排序 对于K不存在的线段的放在一起,对x1进行排序 对于x1相同的对于y1排序
对于K存在的直线 对b进行排序 b相同的对于x1进行排序
排序复杂度Nlogn 在对于在一条直线上的线段O(n)的计算线段数目
总时间复杂度NLOGN这应该是这题最基本的算法
#include
<
stdio.h
>
#include
<
string
.h
>
#include
<
stdlib.h
>
#include
<
math.h
>
![None.gif](/Images/OutliningIndicators/None.gif)
struct
line
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
double x1, y1, x2, y2;
double b, k;
bool ex_k;
}
;
![None.gif](/Images/OutliningIndicators/None.gif)
line l[
10000
];
int
result;
int
cnt;
![None.gif](/Images/OutliningIndicators/None.gif)
void
func(
int
begin,
int
end)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
int i;
int c=0;
double back_x, back_y;
for(i = begin; i <= end; i++)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(l[i].ex_k)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(i == begin || back_x < l[i].x1)
c++;
if(i == begin || back_x < l[i].x2)
back_x=l[i].x2;
}
else
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(i == begin || back_y < l[i].y1)
c++;
if(i == begin || back_y < l[i].y2)
back_y=l[i].y2;
}
}
result += c;
}
![None.gif](/Images/OutliningIndicators/None.gif)
bool
eq(
const
double
a,
const
double
b)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
if(fabs(a-b)<0.00000001)
return 1;
else
return 0;
}
![None.gif](/Images/OutliningIndicators/None.gif)
int
cmp1(
const
void
*
a,
const
void
*
b)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
line * aa = (line *)a;
line * bb = (line *)b;
if(aa->ex_k != bb->ex_k )
return aa->ex_k > bb->ex_k ? 1 : -1;
else
if(aa->ex_k && bb->ex_k)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(!eq(aa->k , bb->k))
return aa->k > bb->k ? 1 : -1;
else
if(!eq(aa->b , bb->b))
return aa->b > bb->b ? 1 : -1;
else
return aa->x1 > bb->x1 ? 1 : -1;
}
else
if(!eq(aa->x1 , bb->x1))
return aa->x1 > bb->x1 ? 1 : -1;
else
return aa->y1 > bb->y1 ? 1 : -1;
}
![None.gif](/Images/OutliningIndicators/None.gif)
int
main()
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
int n;
while(scanf("%d", &n) == 1 && n)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
result = 0;
cnt = 0;
memset(l,0,sizeof(l));
int i;
line ll;
for(i = 0; i < n; i++)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
scanf("%lf%lf%lf%lf", &l[i].x1, &l[i].y1, &l[i].x2, &l[i].y2);
if(l[i].x1==l[i].x2)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
l[i].ex_k=0;
if(l[i].y1 > l[i].y2)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
double temp=l[i].x1;
l[i].x1=l[i].x2;
l[i].x2=temp;
temp=l[i].y1;
l[i].y1=l[i].y2;
l[i].y2=temp;
}
}
else
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
l[i].ex_k=1;
if(l[i].x1 > l[i].x2)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
double temp=l[i].x1;
l[i].x1=l[i].x2;
l[i].x2=temp;
temp=l[i].y1;
l[i].y1=l[i].y2;
l[i].y2=temp;
}
l[i].k=(l[i].y2-l[i].y1)/(l[i].x2-l[i].x1);
l[i].b=l[i].y1-l[i].x1*(l[i].y2-l[i].y1)/(l[i].x2-l[i].x1);
}
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
qsort(l, n , sizeof(l[0]), cmp1);
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
int begin = 0, end = 0;
for(i = 0; i < n; i++)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(i == n-1 || l[i].ex_k != l[i+1].ex_k || !l[i].ex_k&&!eq(l[i].x1 , l[i+1].x1) || !eq(l[i].k , l[i+1].k) || !eq(l[i].b , l[i+1].b) )
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
end = i;
func(begin, end);
begin = i+1;
}
}
printf("%d\n", result);
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
}
return 0;
}