zoukankan      html  css  js  c++  java
  • 导弹防御

    导弹防御

    题目描述:

    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
    ",ans);
        }
    }
  • 相关阅读:
    MySQL按照汉字的拼音排序
    js prepend() 和append()区别
    php获取当月天数及当月第一天及最后一天、上月第一天及最后一天实现方法
    (转)对《30个提高Web程序执行效率的好经验》的理解
    打印数组
    php创建文件并写入信息
    关于iOS地图定位中点击设置->隐私->定位服务 闪退问题
    解决WAMP搭建PHP环境后后局域网其他机器无法访问的问题
    用php怎么改文件名
    JSP HTTP 状态码
  • 原文地址:https://www.cnblogs.com/kczno1fans/p/7805844.html
Copyright © 2011-2022 走看看