当前位置: 代码迷 >> 综合 >> NOIP2018 模拟测试 day1 导弹防御
  详细解决方案

NOIP2018 模拟测试 day1 导弹防御

热度:21   发布时间:2023-12-06 07:59:29.0

题目:导弹防御

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国的总统,请你决定何时开启本国的导弹系统,可以使受到的损害最小。 

思路:
——来自LYD

A 5 9 B 3 7 11 A 11 B 6 16 A 4 10 B 1 7 13 A 4 12 B 0 8 16A: x发射,飞行y,伤害zx+y < X 第一次飞到B B没开着拦截 炸Bx+y > X+TB 炸Bx+2*y 需要A开x+3*y > X+TB 炸Bx+4*y 需要A开x+5*y(2k+1) > (X+TB-x)/y 求k最小值 2kmin+1 = (X+TB-x)/y 下取整 + 1 A:[x+2,x+2k*y] A至少需要在哪个时间段 -> A开启系统的时间的范围 [5,9] 10 -> [5,5] +10 [11,11] 7 [7,11] +7 [4,10] 2 x [4,12] 8 xt t+TAN+M个区间(每个区间有一个价值) 放一个点,让这个点属于的区间价值和最大 1. 线段树,求全局最大值 2. 差分,排序,扫描 5 +10 10 6 -10 0 7 +7 7 12 -7 0 

代码:

#include<bits/stdc++.h> using namespace std;#define maxn 10000 #define maxm 100000000 #define read(x) scanf("%d",&x)struct Node {
     int t,tc,d;Node(){
     }Node(int tt,int dd) {
     t=tt,d=dd;}bool operator < (const Node& oth) const {
     return t<oth.t||(t==oth.t&&d>oth.d);} };int TA,TB,X; int n,m;Node a[maxn+5],b[maxn+5];vector<Node> vec;bool readin() {
     if(-1==read(TA)) return false;read(TB);read(X);read(n),read(m);for(int i=1;i<=n;i++) {
     read(a[i].t),read(a[i].tc),read(a[i].d);}for(int i=1;i<=m;i++) {
     read(b[i].t),read(b[i].tc),read(b[i].d);}return true; }int main() {
     while(readin()) {
     vec.clear();int tot=0;for(int i=1;i<=n;i++) {
     int l=a[i].t+a[i].tc,r=a[i].t+a[i].tc;if(l<X||X+TB<r) continue;tot+=a[i].d;l+=a[i].tc;r=l+(X+TB-l+a[i].tc)/(a[i].tc*2)*(a[i].tc*2);if(r-l>TA) continue;vec.push_back(Node(l,-a[i].d));vec.push_back(Node((l-(TA-(r-l))),a[i].d));}for(int i=1;i<=m;i++) {
     int l=b[i].t+b[i].tc;int r;tot+=b[i].d;if (b[i].t+2*b[i].tc<X) r=b[i].t+b[i].tc;else if (b[i].t+2*b[i].tc>X+TB) r=b[i].t+b[i].tc;else r=(X+TB-b[i].t)/(2*b[i].tc)*(2*b[i].tc)+l;if(r-l>TA) continue;vec.push_back(Node(l,-b[i].d));vec.push_back(Node((l-(TA-(r-l))),b[i].d));}sort(vec.begin(),vec.end());int x=0,ans=0;for(int i=0;i<vec.size();i++) {
     Node y=vec[i];x+=y.d;ans=max(ans,x);}printf("%d\n",tot-ans);}return 0; }