hihocoder 1391 [扫描线]

/*
题意:
两方对阵,互发导弹。防护罩可以让导弹原速反向。
每一枚导弹有发射时间航行时间伤害值。
防护罩也有开启时间和防御时间。
其中一方防护罩开启时间已知,求另一方防护罩合理安排开启时间使得己方受到的伤害最小。
思路:
假设己方的防护罩一只有效,那么我们可以根据对方防护罩的时间算出任何一枚导弹第一次落入己方和最后一次落入己方的时间。
然后类似扫描线的思维处理。
时间的计算可以直接来公式处理,也可以二分下...
比赛最后没出这题,细节问题没处理好,我的锅。


*/

#include<bits/stdc++.h>
using namespace std;
long long ta,tb,x;
struct st{
    void read(){
        scanf("%lld%lld%lld",&ta,&tac,&da);
    }
    long long st,ed,ta,tac,da,id;
};
st ziji[10050],diren[10050],rel[20050],bbb[20050];
bool cmp(st a,st b){
    return a.st<b.st;
}
bool cmp2(st a,st b){
    return a.ed<b.ed;
}
bool ms[20055];
int main(){
    while(scanf("%lld%lld",&ta,&tb)!=EOF){
        memset(ms,0,sizeof(ms));
        scanf("%lld",&x);
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)ziji[i].read();
        for(int i=0;i<m;i++)diren[i].read();
        int num=0;
        long long ans=0;
        for(int i=0;i<n;i++){
            if(ziji[i].ta+ziji[i].tac>x+tb||ziji[i].ta+ziji[i].tac<x)continue;
            ziji[i].st=ziji[i].ta+ziji[i].tac*2;
            if(ziji[i].st+ziji[i].tac>x+tb)ziji[i].ed=ziji[i].st;
            else{
                ziji[i].ed=((x+tb-ziji[i].ta-ziji[i].tac)/(2*ziji[i].tac)+1)*2*ziji[i].tac+ziji[i].ta;
            }
            rel[num++]=ziji[i];
            rel[num-1].id=num-1;
            ans+=ziji[i].da;
        }
        for(int i=0;i<m;i++){
            diren[i].st=diren[i].ta+diren[i].tac;
            if(diren[i].st+diren[i].tac>x+tb||diren[i].st+diren[i].tac<x)diren[i].ed=diren[i].st;
            else{
                diren[i].ed=((x+tb-diren[i].st-diren[i].tac)/(2*diren[i].tac)+1)*2*diren[i].tac+diren[i].st;
            }
            rel[num++]=diren[i];
            rel[num-1].id=num-1;
            ans+=diren[i].da;
        }
        for(int i=0;i<num;i++)bbb[i]=rel[i];
        sort(rel,rel+num,cmp);
        sort(bbb,bbb+num,cmp2);
        long long gg=ans,sst=rel[0].st,bf=0,xx=0;
        for(int i=0;i<num;){
            gg+=bf;
            bf=0;
            sst=rel[i].st;
            while(i<num&&rel[i].st==sst){
                if(rel[i].ed<=sst+ta){
                    bf+=rel[i].da;
                    if(ms[rel[i].id]==0){
                        ms[rel[i].id]=1;
                        gg-=rel[i].da;
                    }
                }
                i++;
            }
            while(xx<num&&bbb[xx].ed<=sst+ta){
                if(ms[bbb[xx].id]==0&&bbb[xx].st>=sst){
                    ms[bbb[xx].id]=1;
                    gg-=bbb[xx].da;
                }
                xx++;
            }
            ans=min(gg,ans);
        }
        printf("%lld
",ans);
    }
}
原文地址:https://www.cnblogs.com/tun117/p/5905424.html