#15. 导弹防御——Yucai OJ第15次测试

问题描述

Country A 与 B 是敌对国家,它们正在一场战争中互相发射导弹。

A 国共发射了 N 枚导弹,其中第 i 枚的发射时间为 Ti  Tai ,花费 Tai  Taci 的时间 飞到 B 国,并可对 B 国造成 Di  Dai 点损害。

B 国共发射了 M 枚导弹,其中第 i 枚的发射时间为 Ti  Tbi ,花费 Tbi  Tbci 的时间 飞到 A 国,并可对 A 国造成 Di  Dbi 点伤害。

不过,两国都有一套导弹防御系统,A 国的导弹防御系统可以在某个连续 TTA 的时间段内开启(其它时间关闭),B 国的导弹系统可以在某个连续 TTB 的时 间段内开启(其它时间关闭)。当拦截系统开启时,所有到达该国的导弹会立即 调转方向按照原本的速度飞向对面国家;当拦截系统关闭时,导弹会对该国造成 损害(拦截系统在时间段端点处,即恰好开启和关闭时也被认为是开启的)。

现在 A 国的情报部门探听到 B 国将于时刻 X 开启导弹系统(在时刻 X+TX+TB 关闭)。作为 A 国的总统,请你决定何时开启本国的导弹系统,可以使受到的损害最小。

输入格式

每个测试点包含多组数据(不超过 50 组),对于每组数据:

第一行两个整数 TTA , TTB ,

第二行一个整数 X ,

第三行两个整数 N , M 。

接下来 N 行每行三个整数 Ti  Tai ,Tai  Taci ,Di  Dai 。

接下来 M 行每行三个整数 Ti  Tbi ,Tbi  Tbci ,Di  Dbi 。

输出格式

对于每组数据,输出 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 0<=N,M<=100 。

对于另外 20%的数据,TA=TA=0 。

对于另外 20%的数据,TB=TB=0 。

对于 100%的数据,0<=TA,TB,X,T,Ta,T,Tb<=10 0<=N,M<=10 1<=D,D<=10 4  0<=TA,TB,X,Tai,Taci,Tbi,Tbci<=108,0<=N,M<=104,1<=Dai,Dbi<=104 。

时空限制

1S/512MB

题解

预处理A和B的导弹,看哪些可以被反弹,求出欲反弹导弹需要覆盖哪些地区,然后排序,枚举,优先队列。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=10100;
 4 long long ta,tb,x,tot,n,m,sum,ans;
 5 long long read(){
 6     long long lin = 0;
 7     char x= getchar();
 8     while(x<'0' || x > '9'){
 9         x = getchar();
10     }
11     while(x >= '0' && x <= '9'){
12         lin = (lin << 1) + (lin << 3) + x - '0';
13         x = getchar();
14     }
15     return lin;
16 }
17 struct st{
18     long long st,en,tim,att;
19 }a[maxn << 1],s[maxn << 1];
20 bool com(st a,st b){
21     return a.en < b.en;
22 }
23 void putin(){
24     for(long long i=1;i<=n;i++){
25         a[i].st = read();
26         a[i].tim = read();
27         a[i].att = read();
28         a[i].en = 0;
29         if(a[i].st + a[i].tim >= x && a[i].st + a[i].tim <= x + tb){
30             sum += a[i].att;
31             tot++;
32             s[tot] = a[i];
33             long long k = (x + tb - a[i].st - a[i].tim) % (a[i].tim << 1);
34             s[tot].en = x + tb - k + a[i].tim;
35             s[tot].st += s[tot].tim << 1;
36         }
37     }
38     for(long long i=1;i<=m;i++){
39         a[i].st = read();
40         a[i].tim = read();
41         a[i].att = read();
42         a[i].en = 0;
43         tot++;
44         sum += a[i].att;
45         s[tot] = a[i];
46         long long k = (x + tb - a[i].st) % (a[i].tim << 1);
47         s[tot].en = x + tb - k + a[i].tim;
48         s[tot].st += s[tot].tim;
49         if(s[tot].st + s[tot].tim < x || s[tot].st + s[tot].tim > x + tb){
50             s[tot].en = s[tot].st;
51         }
52     }    
53 }
54 bool operator <(st a,st b){
55     return a.st > b.st;
56 }
57 int main(){
58     while(cin>>ta>>tb){
59         sum = 0;
60         tot = 0;
61         x = read();
62         n = read();
63         m = read();
64         putin();
65         sort(s+1,s+1+tot,com);
66         ans = sum;
67         priority_queue <st> q;
68         for(long long i=1;i<=tot;i++){
69             q.push(s[i]);
70             sum -= s[i].att;
71             while(q.top().st < s[i].en - ta && !q.empty()){
72                 sum += q.top().att;
73                 q.pop();
74             }
75             ans = min(ans,sum);
76         }
77         cout<<ans<<endl;
78     }
79     return 0;
80 }
标程

 

转载于:https://www.cnblogs.com/VOCAOID/p/9558284.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值