浙大月赛——ZOJ Problem Set 3574

直线x=a,x=b

又有n条线段

求吧区域分成几个空间部分

顶点-线段+空间=3

把线段与两条直线相交的点ll,rr求出来

按min(ll,rr)排序判断来降低时间复杂度

View Code
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;

struct data
{
double ll,rr;
double duan;
double min;
}s[30099];

double cmp(data a,data b)
{
return a.min<b.min;
}

int main()
{
double a,b;
while(scanf("%lf%lf",&a,&b)!=EOF)
{
int n;
scanf("%d",&n);
int i,j;
double k,c,min;
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&k,&c);
s[i].ll=k*a+c;
s[i].rr=k*b+c;
s[i].duan=1;

min=s[i].ll;
if(min>s[i].rr)
min=s[i].rr;
s[i].min=min;
}
sort(&s[1],&s[n+1],cmp);

double dian=0,max;
for(i=1;i<=n;i++)
{
max=s[i].ll;
if(max<s[i].rr)
max=s[i].rr;

for(j=i+1;j<=n;j++)
{
if((s[j].rr>s[i].rr&&s[j].ll<s[i].ll)||(s[j].rr<s[i].rr&&s[j].ll>s[i].ll))
{
s[j].duan++;
s[i].duan++;
dian++;
}
if(max<=s[j].min)
break;
}
}

dian+=n*2;
double all=0;
for(i=1;i<=n;i++)
{
all+=s[i].duan;
}
all+=(n-1)*2;

double temp=3-dian+all;
printf("%.0lf\n",temp);
}

return 0;
}



原文地址:https://www.cnblogs.com/huhuuu/p/2368149.html