您的位置:首页 > 理论基础 > 计算机网络

ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 I

2016-09-25 00:44 429 查看
这题应该说没什么算法,最多就是一些技巧在里面;

关键是题意真是复杂,给的变量就很多。然后根据已知的变量,我们可以求出每个导弹第一次攻击到A的时间st和最后一次攻击到的时候ed(假设A会弹回去的最后一次);防御时间必须 包含[st,ed],这个防御才能成功 

问题就转化为 求一个固定长度的区间,使得这个区间覆盖的可防御伤害最大。

怎么求这个区间的位置呢?

只要把每个导弹的st和ed两个点放到一个数组里,然后把所有点排序;然后把防御区间从左往右移,碰到一个左端点,当前覆盖的防御值减掉它会造成的伤害,碰到一个右端点加上去,就可以在n 时间内求出最大可防御伤害,最后的答案就是 A总的可能能受到的伤害 - 最大可防御的伤害

【代码】

#include<stdio.h>
#include<iostream>
#include<memory.h>
#include<stdlib.h>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<algorithm>
using namespace std;
const int MAXN = 100005;
int LTA, LTB;
int XB;
int N, M;
int ta[MAXN], tb[MAXN];
int fa[MAXN], fb[MAXN];
int da[MAXN], db[MAXN];
struct Node
{
int d;
int t;
int len;
int flag;
}node[2 * MAXN];
int nodeLen = 0;
void AddNode(int t, int len, int flag, int d)
{
node[nodeLen].t = t;
node[nodeLen].len = len;
node[nodeLen].flag = flag;
node[nodeLen].d = d;
nodeLen++;
}
bool comp(Node a, Node b)
{
return a.t < b.t;
}

int main(void) {
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
int i;
int T;
int stB, edB;
int st, ed, cnt;
while (scanf("%d%d", <A, <B) != EOF)
{
int total = 0;
scanf("%d", &XB);
stB = XB;
edB = XB + LTB;
scanf("%d%d", &N, &M);
for (i = 0; i < N; i++)
{
scanf("%d%d%d", &ta[i], &fa[i], &da[i]);
total += da[i];
}
for (i = 0; i < M; i++)
{
scanf("%d%d%d", &tb[i], &fb[i], &db[i]);
total += db[i];
}
nodeLen = 0;
for (i = 0; i < N; i++)
{
if (ta[i] + fa[i] >= stB && ta[i] + fa[i] <= edB)
{
st = ta[i] + fa[i] * 2;
cnt = (edB - ta[i] - fa[i]) / fa[i];
if (cnt % 2 == 0)
{
ed = ta[i] + fa[i] + fa[i] * (cnt + 1);
}
else
{
ed = ta[i] + fa[i] + fa[i] * cnt;
}
AddNode(st, ed -st, 0, da[i]);
AddNode(ed, ed -st, 1, da[i]);
}
else
{
total -= da[i];
}
}
for (i = 0; i < M; i++)
{
if (tb[i] + fb[i] * 2 >= stB && tb[i] + fb[i] * 2 <= edB)
{
st = tb[i] + fb[i];
cnt = (edB - tb[i] - 2 * fb[i]) / fb[i];
if (cnt % 2 == 0)
{
ed = tb[i] + 2 * fb[i] + fb[i] * (cnt + 1);
}
else
{
ed = tb[i] + 2 * fb[i] + fb[i] * cnt;
}
AddNode(st, ed - st, 0, db[i]);
AddNode(ed, ed - st, 1, db[i]);
}
else
{
st = tb[i] + fb[i];
ed = st;
AddNode(st, ed - st, 0, db[i]);
AddNode(ed, ed - st, 1, db[i]);
}
}
sort(node, node + nodeLen, comp);
int res = 0;
int maxRes = 0;
st = 0;
ed = 0;
while (st < nodeLen)
{
int t = node[st].t;
while (ed < nodeLen && node[ed].t <= t + LTA)
{
if (node[ed].flag == 1 && node[ed].len <= LTA)
{
res += node[ed].d;
}
ed++;
}
if (res > maxRes)
{
maxRes = res;
}
while (st < nodeLen && node[st].t == t)
{
if (node[st].flag == 0 && node[st].len <= LTA)
{
res -= node[st].d;
}
st++;
}
}
printf("%d\n", total - maxRes);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐