导弹防御

导弹防御

题目描述:

Country A 与 B 是敌对国家,它们正在一场战争中互相发射导弹。
A 国共发射了 N 枚导弹,其中第 i 枚的发射时间为 Ta_i,花费 Tac_i 的时间飞到 B 国,并可对 B 国造成 Da_i 点损害。 .
B 国共发射了 M 枚导弹,其中第 i 枚的发射时间为 Tb_i,花费 Tbc_i 的时间飞到 A 国,并可对 A 国造成 Db_i 点伤害。 .
不过,两国都有一套导弹防御系统, A 国的导弹防御系统可以在某个连续TA 的时间段内开启(其它时间关闭), B 国的导弹系统可以在某个连续 TB 的时间段内开启(其它时间关闭)。当拦截系统开启时,所有到达该国的导弹会立即调转方向按照原本的速度飞向对面国家;当拦截系统关闭时,导弹会对该国造成损害(拦截系统在时间段端点处,即恰好开启和关闭时也被认为是开启的)。
现在 A 国的情报部门探听到 B 国将于时刻 X 开启导弹系统(在时刻 X+TB关闭)。作为 A 国的总统,请你决定何时开启本国的导弹系统,可以使受到的损害最小。

输入格式:

每个测试点包含多组数据(不超过 50 组),对于每组数据:
第一行两个整数 TA, TB,第二行一个整数 X,第三行两个整数 N, M。
接下来 N 行每行三个整数 Ta_i, Tac_i and Da_i。
接下来 M 行每行三个整数 Tb_i, Tbc_i and Db_i。

输出格式:

对于每组数据,输出 A 国受到的最小损害。

样例输入:

2 2
2
1 0
1 1 10
4 5
3
2 2
1 2 10
1 5 7
1 3 2
0 4 8

样例输出:

0
17

提示:

【数据规模与约定】
对于 20%的数据, 0 <= N,M <= 100。
对于另外 20%的数据, TA=0。
对于另外 20%的数据, TB=0。
对于 100%的数据, 0 <= TA, TB, X, Ta_i, Tac_i, Tb_i, Tbc_i <= 100000000, 0<= N, M <= 10000, 1 <= Da_i, Db_i <= 10000。

时间限制:1000ms
空间限制:512MByte

 

思路很清晰,可是想要优化就需要一些小技巧。。。

先将输入的A的攻击预处理,处理出那些攻击可以被B的盾弹回来,然后预处理B的攻击,A和B的攻击都要求出

如果A的盾可以把攻击反弹回去的话A的盾需要至少覆盖那些位置!!!

然后排序一下,依次枚举终点,然后(覆盖位置的终点)优先队列搞搞就好了。。。

#include<bits/stdc++.h>
#define maxn 10100
#define ll long long
using namespace std;
ll ta,tb,x,tot,n,m,sum,ans;

inline ll read()
{
    ll lin = 0;
    char x = getchar();
    while(x < '0' || x > '9') x = getchar();
    while(x >= '0' && x <= '9')
    {
        lin = (lin << 1) + (lin << 3) + x - '0';
        x = getchar();
    }
    return lin;
}

struct st{
    ll st,en,tim,att;
}a[maxn << 1],s[maxn << 1];

bool com(st a,st b)
{
    return a.en < b.en;
}

void putin()
{
    for(ll i=1;i<=n;i++)
    {
        a[i].st = read();
        a[i].tim = read();
        a[i].att = read();
        a[i].en = 0;
        if(a[i].st + a[i].tim >= x && a[i].st + a[i].tim <= x + tb)
        {
            sum += a[i].att;
            tot++;
            s[tot] = a[i];
            ll k = (x + tb - a[i].st - a[i].tim) % (a[i].tim << 1);
            s[tot].en = x + tb - k + a[i].tim;
            s[tot].st += s[tot].tim << 1;
        }
    }
    for(ll i=1;i<=m;i++)
    {
        a[i].st = read();
        a[i].tim = read();
        a[i].att = read();
        a[i].en = 0;
        tot++;
        sum += a[i].att;
        s[tot] = a[i];
        ll k = (x + tb - a[i].st) % (a[i].tim << 1);
        s[tot].en = x + tb - k + a[i].tim;
        s[tot].st += s[tot].tim;
        if(s[tot].st + s[tot].tim < x || s[tot].st + s[tot].tim > x + tb) s[tot].en = s[tot].st;
    }    
}

bool operator <(st a,st b)
{
    return a.st > b.st;
}

int main(){
    while(scanf("%lld%lld",&ta,&tb) != EOF)
    {
        
        sum = 0;
        tot = 0;
        x = read();
        n = read();
        m = read();
        putin();
        sort(s+1,s+1+tot,com);
        ans = sum;
        priority_queue <st> q;
        for(ll i=1;i<=tot;i++)
        {
            q.push(s[i]);
            sum -= s[i].att;
            while(q.top().st < s[i].en - ta && !q.empty())
            {
                sum += q.top().att;
                q.pop();
            }
            ans = min(ans,sum);
        }
        printf("%lld\n",ans);
    }
}

 

posted @ 2017-11-08 19:54  cc123321  阅读(231)  评论(0编辑  收藏  举报