2020CCPC河南省赛 C题 我得重新集结部队(模拟题)

问题 C: 我得重新集结部队

时间限制: 1 Sec 内存限制: 128 MB

[状态] [讨论版] [提交] [命题人:admin]

题目描述

为了保护科普卢星区的和平,大主教阿塔尼斯每时每刻都在指挥部队抗击肆虐的虫群。最近,阿塔尼斯把目光投向了又一颗布满虫群的星球。在这次行动中,阿塔尼斯计划使用狂热者铲除星球上的虫群威胁。
狂热者是星灵的基本近战兵种,每个狂热者有一个攻击力 atk 和一个攻击范围 r。在狂热者发动攻击时,他会冲向距离最近的异虫,在这只异虫处释放 3 次威力强大的旋风斩。若有多只距离最近的异虫,他会选择最早出现的那只。若当前没有存活的异虫,那么这只狂热者会在原地释放旋风斩。每次旋风斩会对所有与攻击者距离小于等于 r 的异虫进行攻击,对每只异虫造成 atk 的伤害(生命值减少 atk)。
当然,这些异虫也是不好惹的。每只异虫具有初始生命值 h,当生命值小于等于 0 时,该异虫将会死亡(并离开战场)。但是,在一次攻击中,若一只异虫受到 3 次旋风斩后仍未死亡,那么它将会对进攻的狂热者进行反击,使这个狂热者不得不离开战场。
在整个战役中,按照时间顺序依次发生了 n 个事件,事件有以下两种:

  1. 异虫出现。一只初始生命值为 h 的异虫单位出现在 (x,y)坐标。
  2. 折跃狂热者。一个狂热者被折跃到了 (x,y) 坐标,冲向距离最近的异虫(若存在)并发动 3 次旋风斩。若此后该狂热者没有受到反击,那么他将会一直留在战场,但是不会继续进行攻击。

你作为阿塔尼斯的副官,想知道战场的最终情况:每个狂热者是否离开了战场,以及每只异虫是否死亡。

输入

第一行包含一个整数 n (1≤n≤2×103),代表事件的数量。
接下来 n 行,每行给出一种事件,格式为以下两种之一:
1 x y h,代表一个生命值为 h 的异虫出现在了坐标 (x,y)。
2 x y atk r,代表一个攻击力为 atk,攻击半径为 r 的狂热者被折跃到了坐标 (x,y),并立即进行攻击。
上述所有的x,y,r 均为整数,满足 0≤∣x∣,∣y∣,r≤108;所有的 atk,h 均为整数,满足 1≤atk,h≤108。

输出

输出 n 行,第 i 行表示第 i 个事件中出现的异虫或狂热者最终是否留在战场。Yes 表示异虫未死亡或狂热者未离开战场,No 表示异虫死亡或狂热者离开战场,大小写不敏感

样例输入

5
1 0 0 4
1 0 1 8
2 1 0 1 1
2 1 0 1 1
2 1 0 1 1

样例输出

No
No
No
No
Yes

提示

在样例中,发生了如下事件:

  1. 事件 1 中,在 (0,0)处出现了一只异虫,其生命值为 4。
  2. 事件 2 中,在 (0,1)处新出现了一只异虫,其生命值为 8。
  3. 事件 3 中,在 (1,0) 处折跃一只攻击力为 1,攻击半径为 1 的狂热者,他移动到坐标 (0,0) 后,发动 3 次旋风斩。异虫 1,2 分别剩余生命值 1,5,随后狂热者受到反击离开战场。
  4. 事件 4 中,在 (1,0) 处折跃一只攻击力为 1,攻击半径为 1 的狂热者,他移动到坐标 (0,0) 后,发动 3 次旋风斩。异虫 1 死亡,异虫 2 剩余生命值 2,随后狂热者受到反击离开战场。
  5. 事件 5 中,在 (1,0) 处折跃一只攻击力为 1,攻击半径为 1 的狂热者,他移动到坐标 (0,1) 后,发动 3 次旋风斩。异虫 2 死亡,狂热者留在战场。

因而,最终所有异虫死亡,只有狂热者 5 留在战场。


C++代码如下

#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;

const int N = 2005;

struct {
    
    
	LL x;
	LL y;
	LL h;
}a[N];

struct {
    
    
	LL x;
	LL y;
	LL atk;
	LL r;
	int cnt;//是否存活 
}ku[N];

int g[N];
LL x,y,h,atk,r;

int main()
{
    
    
	
	int T;
	int flag = 0;//chong
	int flag2 = 0;//kuang
	cin >> T;
	for(int k = 0; k < T; k ++)
	{
    
    
		int c;
		cin >> c;
		g[k] = c;
		if(c == 1)
		{
    
    
			cin >> x >> y >> h;
			a[flag].x = x;
			a[flag].y = y;
			a[flag].h = h;
			flag ++;
		}
		else if(c == 2)
		{
    
    
			cin >> x >> y >> atk >> r;
			ku[flag2].x = x;
			ku[flag2].y = y;
			ku[flag2].atk = atk;
			ku[flag2].r = r;
			ku[flag2].cnt = 1;
 

			long long minn = 2e18;
			int index = 0;
	
			for(int i = 0; i < flag; i ++) //狂热者跃迁 
			{
    
    
				long long d = (ku[flag2].x - a[i].x) * (ku[flag2].x - a[i].x) + (ku[flag2].y - a[i].y) * (ku[flag2].y - a[i].y); 
				if( minn > d && a[i].h > 0)//找到目标 
				{
    
    
					minn = d;
					index = i;	
				}
			}
			
			if(minn == 2e18) //场上没有虫子,直接跳过 
			{
    
    
				flag2 ++;
				continue;
			}
			
			LL minx = a[index].x, miny = a[index].y;//更新当前狂热者位置 
		
			for(int i = 0; i < flag; i ++) //放大招 
			{
    
    
				long long d = (minx - a[i].x) * (minx - a[i].x) + (miny - a[i].y)*(miny - a[i].y);  
				if(r * r >=  d && a[i].h > 0)
				{
    
    
					a[i].h -= 3 * atk;
					if(a[i].h <= 0)
					{
    
    
						a[i].h = 0;
					}
					else
					{
    
    
						ku[flag2].cnt = 0; //虫子没有死 ,狂热者受到反击 死亡 
					}
				}
			}
			flag2 ++;
		}	
	}
	
	int j= 0,k = 0;
	for(int i = 0; i < T; i ++)
	{
    
    
		
		if(g[i] == 1)
		{
    
    
			if(a[j].h > 0) cout<< "Yes\n";
			else cout << "No\n";
			j ++;
		}
		else if(g[i] == 2)
		{
    
    
			if(ku[k].cnt == 1) cout << "Yes\n";
			else cout << "No\n";
			k ++; 
		}
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/diviner_s/article/details/110238806