ZOJ 3525 Disappearance

题目链接Disappearance
题意:每一个物品有 B,W,H,S 四种属性,问能否选出一个物品的集合,使得前三种属性的极值小于给定值,且 S 属性的和最小,如果答案不为负数,输出给定的字符串。
解法:注意到N只有 1000 ,所以我们可以直接枚举第一维,接下来的做法就和POJ 2482
一样了,线段树+扫描线即可。

#include <bits/stdc++.h>

using namespace std;

const int N = 1005;
struct Line{
    int l,r,h,d;
}l[N<<1];
struct Node{
    int l,r,v,tg;
}a[N<<3];

inline void PushUp(int i){
    a[i].v=min(a[i<<1].v,a[i<<1|1].v);
}

void Build(int i,int l,int r){
    a[i].l=l;
    a[i].r=r;
    a[i].v=a[i].tg=0;

    if(l==r)
        return ;

    int mid=l+r>>1;
    Build(i<<1,l,mid);
    Build(i<<1|1,mid+1,r);
    PushUp(i);
}

inline void PushDown(int i){
    if(a[i].tg){
        a[i<<1].v+=a[i].tg;
        a[i<<1].tg+=a[i].tg;
        a[i<<1|1].v+=a[i].tg;
        a[i<<1|1].tg+=a[i].tg;
        a[i].tg=0;
    }
}

void Add(int i,int l,int r,int d){
    if(l<=a[i].l&&a[i].r<=r){
        a[i].v+=d;
        a[i].tg+=d;
        return ;
    }

    PushDown(i);
    if(l<=a[i<<1].r)
        Add(i<<1,l,r,d);
    if(a[i<<1|1].l<=r)
        Add(i<<1|1,l,r,d);
    PushUp(i);
}

struct BWH{
    int x,y,z,s;
}bwh[N];
set<int>Sx;
map<int,int>My;
int t[N<<1];

inline bool cmp(const Line& q,const Line& w){
    if(q.h==w.h)
        return q.d<w.d;
    return q.h<w.h;
}

int main(){
    int n,b,w,h;
    while(scanf("%d",&n)==1){
        Sx.clear();
        My.clear();
        for(int i=1;i<=n;i++){
            scanf("%d %d %d %d",&bwh[i].x,&bwh[i].y,&bwh[i].z,&bwh[i].s);
            bwh[i].y*=2;
            bwh[i].z*=2;
            Sx.insert(bwh[i].x);
        }
        scanf("%d %d %d",&b,&w,&h);
        w*=2;
        h*=2;
        int ans=0;
        for(set<int>::iterator it=Sx.begin();it!=Sx.end();it++){
            int c=(*it),cnt=0,tp=0;
            My.clear();
            for(int i=1;i<=n;i++)
                if(bwh[i].s<0&&c<=bwh[i].x&&bwh[i].x<=c+b){
                    // cout<<bwh[i].y<<' '<<w/2<<endl;
                    l[cnt].l=bwh[i].y-w/2;
                    l[cnt].r=bwh[i].y+w/2;
                    t[cnt]=l[cnt].l;
                    l[cnt].h=bwh[i].z-h/2;
                    l[cnt++].d=bwh[i].s;

                    l[cnt].l=bwh[i].y-w/2;
                    l[cnt].r=bwh[i].y+w/2;
                    t[cnt]=l[cnt].r;
                    l[cnt].h=bwh[i].z+h/2;
                    l[cnt++].d=-bwh[i].s;
                }
            sort(t,t+cnt);
            int len=unique(t,t+cnt)-t;
            for(int i=0;i<len;i++)
                My[t[i]]=i+1;
            sort(l,l+cnt,cmp);
            if(len){
                Build(1,1,len);
                for(int i=0;i<cnt;i++){
                    tp=min(tp,a[1].v);
                    Add(1,My[l[i].l],My[l[i].r],l[i].d);
                }
            }
            ans=min(ans,tp);
        }
        if(ans<0)
            printf("%d\n",ans);
        else
            puts("Error 404, mahou shoujo not found!");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值