您的位置:首页 > 移动开发

ZOJ 3525 Disappearance(扫描线)

2013-09-18 22:21 232 查看
题意:有三维的空间里有N个点(N<5000),要求用一个长方体LB*LW*LH去包围一些点,使得长方体内的点的权值和最小。

因为N只有5000,起先我们的方法是暴力去枚举两维,即按X排序,找出点彼此间距离不超过LB的点,然后将这些点按Y排序,在线段树中放进Y之间最大距离不超过LW的点。。但是这样死活过不了。。最后枚举一维,直接按X排序,然后就是poj 2482的做法了。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=5005;

int n;
int LB,LW,LH;

struct REC
{
int x,y,z,w;
REC(){}
REC(int x,int y,int z,int w) :
x(x),y(y),z(z),w(w) {}
bool operator<(const REC &B)const
{
return x<B.x;
}
};
struct Line
{
int x,y1,y2,w;
Line(){}
Line(int x,int y1,int y2,int w) :
x(x),y1(y1),y2(y2),w(w) {}
bool operator<(const Line &B)const
{
return x<B.x||(x==B.x&&w>B.w);
}
};

vector<REC> rec;
vector<Line> line;

struct Segtree
{
int mx[N*4],delay[N*4];
void fun(int ind,int valu)
{
mx[ind]+=valu; delay[ind]+=valu;
}
void PushDown(int ind)
{
if(delay[ind])
{
fun(LL(ind),delay[ind]);
fun(RR(ind),delay[ind]);
delay[ind]=0;
}
}
void PushUp(int ind)
{
mx[ind]=max(mx[LL(ind)],mx[RR(ind)]);
}
void build(int lft,int rht,int ind)
{
mx[ind]=delay[ind]=0;
if(lft!=rht)
{
int mid=MID(lft,rht);
build(lft,mid,LL(ind));
build(mid+1,rht,RR(ind));
}
}
void updata(int st,int ed,int valu,int lft,int rht,int ind)
{
if(st<=lft&&rht<=ed) fun(ind,valu);
else
{
PushDown(ind);
int mid=MID(lft,rht);
if(st<=mid) updata(st,ed,valu,lft,mid,LL(ind));
if(ed> mid) updata(st,ed,valu,mid+1,rht,RR(ind));
PushUp(ind);
}
}
}seg;
int calc(int st,int ed)
{
line.clear();
for(int i=st;i<=ed;i++)
{
int y=rec[i].y;
int z=rec[i].z;
int w=rec[i].w;

line.push_back(Line(y,z,z+LH,w));
line.push_back(Line(y+LW,z,z+LH,-w));
}
sort(line.begin(),line.end());

seg.build(0,N,1);
int len=(int)line.size(),mx=0;
for(int i=0;i<len;i++)
{
seg.updata(line[i].y1,line[i].y2,line[i].w,0,N,1);
mx=max(mx,seg.mx[1]);
}
return mx;
}
int main()
{
// freopen("in.txt","r",stdin);

while(scanf("%d",&n)!=EOF)
{
rec.clear(); line.clear();
for(int i=0;i<n;i++)
{
int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d);
if(d>=0) continue;
a+=1000; b+=1000; c+=1000;
rec.push_back(REC(a,b,c,-d));
}

scanf("%d%d%d",&LB,&LW,&LH);

if(rec.size()==0)
{
puts("Error 404, mahou shoujo not found!");
continue;
}

n=(int)rec.size();
sort(rec.begin(),rec.end());

int ind1=0,ind2=0,mx=0;
while(ind1<n)
{
while(ind2<n&&rec[ind2].x-rec[ind1].x<=LB) ind2++;
mx=max(mx,calc(ind1,ind2-1));
if(ind2==n) break;
while(ind1+1<n&&rec[ind1].x==rec[ind1+1].x) ind1++;
ind1++;
}
printf("%d\n",-mx);
}
return 0;
}


死活过不了的做法。。贴出来,说不定以后想到哪里挂了。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=5005;

struct REC
{
int x,y,z,w;
REC(){}
REC(int x,int y,int z,int w) :
x(x),y(y),z(z),w(w) {}
void print()
{
cout<<x<<" "<<y<<" "<<z<<" "<<w<<endl;
}
};
bool cmpX(const REC &A,const REC &B)
{
return A.x<B.x;
}
bool cmpY(const REC &A,const REC &B)
{
return A.y<B.y;
}

int n,LB,LW,LH,ans;
vector<REC> rec;
vector<REC> order;

struct Segtree
{
int mx[N*4],delay[N*4];
void PushUp(int ind)
{
mx[ind]=max(mx[LL(ind)],mx[RR(ind)]);
}
void fun(int ind,int valu)
{
mx[ind]+=valu;
delay[ind]+=valu;
}
void PushDown(int ind)
{
if(delay[ind])
{
fun(LL(ind),delay[ind]);
fun(RR(ind),delay[ind]);
delay[ind]=0;
}
}
void build(int lft,int rht,int ind)
{
mx[ind]=delay[ind]=0;

if(lft!=rht)
{
int mid=MID(lft,rht);
build(lft,mid,LL(ind));
build(mid+1,rht,RR(ind));
}
}
void updata(int st,int ed,int valu,int lft,int rht,int ind)
{
if(st<=lft&&rht<=ed) fun(ind,valu);
else
{
PushDown(ind);
int mid=MID(lft,rht);
if(st<=mid) updata(st,ed,valu,lft,mid,LL(ind));
if(ed> mid) updata(st,ed,valu,mid+1,rht,RR(ind));
PushUp(ind);
}
}
}seg;

void fun(int st,int ed)
{
seg.build(0,N,1);
order.clear();

for(int i=st;i<=ed;i++) order.push_back(rec[i]);
sort(order.begin(),order.end(),cmpY);

int len=(int)order.size();
int ind1=0,ind2=0;

while(ind1<len)
{
int y1=order[ind1].y;
int z1=order[ind1].z;
int w1=order[ind1].w;
while(ind2<len)
{
int y2=order[ind2].y;
int z2=order[ind2].z;
int w2=order[ind2].w;
if(y2-y1<=LW)
{
seg.updata(z2,z2+LH,w2,0,N,1);
ans=max(ans,seg.mx[1]);
ind2++;
}
else break;
}
seg.updata(z1,z1+LH,-w1,0,N,1);
ans=max(ans,seg.mx[1]);
ind1++;
}
}

int main()
{
//freopen("in.txt","r",stdin);

while(scanf("%d",&n)!=EOF)
{
ans=0;
rec.clear();  order.clear();

for(int i=0;i<n;i++)
{
int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d);
if(d>=0) continue;
a+=1000; b+=1000; c+=1000;
rec.push_back(REC(a,b,c,-d));
}

scanf("%d%d%d",&LB,&LW,&LH);

if(rec.size()==0)
{
puts("Error 404, mahou shoujo not found!");
continue;
}

sort(rec.begin(),rec.end(),cmpX);

int ind1=0,ind2=0;
while(ind1<n)
{
while(ind2<n&&rec[ind2].x-rec[ind1].x<=LB) ind2++;
fun(ind1,ind2);
while(ind1+1<n&&rec[ind1].x==rec[ind1+1].x) ind1++;
ind1++;
}
printf("%d\n",-ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: