导弹防御
题目描述:
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); } }