/*
本算法的缺点 在于开的空间太大
分三类情况
线段
(-10,-1)在负区间
(-10,10)双区间
(1,10)正区间
一下给出正区间的代码,已考虑小数
思路是
绝对正区间,覆盖到数轴 sz[]数组上 小数部分 用sum1 累计
*/
#include
using namespace std;
#define max 1000 //数轴长度
int sz[max];
#define n 10 //测试线段条数 坐标入下(a[],b[])
/* 0 1 2 3 4 5 6
double a[2*n]={1,3,5,7,9,11,13,15,17,19};
double b[2*n]={2,4,6,8,10,12,14,16,18,20};
*/
double a[2*n];
double b[2*n];
int add=n;//添加的线段下标
double funadd(int s,int t)
{
for(int i=s;i<=t;i++)
{
sz[i]=1;
}
}
double fun()
//数轴上置1 小数部分 用sum1 累计 sum2为整数部分求和
{ double sum=0;double sum1=0;double sum2=0;
int s=0; int t=0;
for(int i=0;i<2*n;i++)
{
if(a[i]==b[i])continue;//未处理部分为 0 就好了 不知道 初始化;
if(a[i]>b[i])swap(a[i],b[i]);
if(a[i]<0&&b[i]<0){tmp=-a[i];a[i]=-b[i];b[i]=tmp;}//均为负数的处理方法
if(a[i]<0&&b[i]>0){a[add]=0;b[add]=-a[i];add++;a[i]=0;}//双区间的截断处理方法 产生新的区间 放到未处理的数组对中
s=ceil(a[i]);t=floor(b[i]);
sum1+=s-a[i];sum1+=b[i]-t;
funadd(a[i],b[i]);
}
for(int i=0;i<2*max;i++)
{
if(sz[i]==1)sum2+=1;
}
sum=sum1+sum2;
return sum;
}
//负数的处理 转正 (-5,-1)-->(1,5)
//(-10,10)这种 分为2部分
int main()
{
for(int i=0;i
网页名称:多线段覆盖求覆盖区间的总和
网站链接:http://njwzjz.com/article/jgihgs.html