贪心算法之泥坑问题
地上有很多泥坑需要木板去填补,给出固定木板长度,可以把泥坑转化成点的坐标,例如坑(1,6),只需要填补1.2.3.4.5即可
起初有一个写法非常简单的想法,就是用一个数组来标记需要填补的点,然后for循环实现,但是没注意点的坐标的大小是十的九次方,而我只当作泥坑的大小是十的五次方,
#include<iostream>
#include<cstring>
using namespace std;
int c[10005];
int main()
{
int l,x,y,sum=0,i,j,n,m=0;
memset(c,0,sizeof(c));
cin >> n>>l;
for(i=0;i<n;i++)
{
cin >>x>>y;
for(j=x;j<y;j++)
{
c[j]++;
}
m=max(m,y);
}
for(i=0;i<=m;i++)
{
if(c[i]!=0) {sum++;i+=(l-1);}
}
cout << sum<<endl;
return 0;
}
怪不得我一直在缩短没必要的代码之后仍然runtime error,数组的范围开的不够大
但显然,数组的范围也开不到10的九次方,经过测试,数组最大可以开到10的八次方,
然后转用vector,但他只能顺序输入,不可以随机挑选位置赋值,所以只能改用另一个方法,利用结构体直接顺序判断,通过比较泥坑的长度和木板的长度来放木板,再考虑木板是否比下一次的右端点值还要大,如果大,就直接continue就可以了
#include<iostream>
#include<algorithm>
using namespace std;
struct xian
{
int a,b;
}x[10004];
bool cmp(xian x,xian y)
{
return x.a<y.a;
}
int main()
{
int l,n,t=0,r=0;
long long int sum=0;
cin >> n>>l;
for(int i=0;i<n;i++)
{
cin >>x[i].a>>x[i].b;
}
sort(x,x+n,cmp);
for(int i=0;i<n;i++)
{
if(r>=x[i].b) continue;//所放木板的右端比此次的泥坑右端还要大,就不需要在放了
if(r>x[i].a) x[i].a=r;//更改左端点值的位置
t=x[i].b-x[i].a;
if(t%l==0)
{
sum+=t/l;
r=x[i].a+t;
}
else
{
sum+=t/l+1;
r=x[i].a+(t/l+1)*l;
}
}
cout << sum<< endl;
return 0;
}