NOIP2018 模拟测试 day1 导弹防御

版权声明:欢迎转载欢迎评论! https://blog.csdn.net/rabbit_ZAR/article/details/82989548

题目:导弹防御

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        16

A:  x发射,飞行y,伤害z
 
 x+y < X  第一次飞到B B没开着拦截 炸B
 x+y > X+TB  炸B
 x+2*y 需要A开
 x+3*y > X+TB 炸B
 x+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    x

t  t+TA


N+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;
}

猜你喜欢

转载自blog.csdn.net/rabbit_ZAR/article/details/82989548