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

来源:互联网 发布:color for mac 编辑:程序博客网 时间:2024/04/27 18:32

转载:http://blog.csdn.net/angon823/article/details/52655138


这题应该说没什么算法,最多就是一些技巧在里面;

关键是题意真是复杂,给的变量就很多。然后根据已知的变量,我们可以求出每个导弹第一次攻击到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);#endifint 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;}

代码菜鸟,如有错误,请多包涵!!!

如有帮助记得支持我一下,谢谢!!!

0 0
原创粉丝点击