2692: 我得重新集结部队

 

时间限制: 1 Sec  内存限制: 128 MB
提交: 134  解决: 30
[状态] [讨论版] [提交] [命题人: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 表示异虫死亡或狂热者离开战场,大小写不敏感。

样例输入 Copy

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

样例输出 Copy

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 留在战场。


#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<set>
using namespace std;
const long long inf=1e17+10;
const int maxn=10010;

struct bug{
	
	int id;
	int x,y;
	int h;
	
	bug(){}
	
	bug(int _id,int _x,int _y,int _h){
		
		id=_id;
		x=_x;
		y=_y;
		h=_h;
	}
};

int n;
int k,x,y;
int atk,r,h;
vector<bug> bugs;
vector<bool> ans;


bool getPoint(int &newX,int &newY){
	
	bool judge=false;
	bug ans;
	long long Min=-1;
	// x y atk r
	int len = bugs.size();
	
	if(len==0) {
 
		return false;
	}
		
	for(int i=0;i<len;i++){
		
		bug tmp = bugs[i];
		
		if(tmp.h<=0) continue;
		
		judge = true;
		
		long long distance = (long long) ( (long long) (x-tmp.x) * (x-tmp.x) + (long long) (y-tmp.y) * (y-tmp.y) );
		
//		cout<<"distance  "<<distance<<endl;
		
		if(Min==-1) {
		
			Min=distance;
			ans = tmp;
		}
		else if(distance < Min){
			
			Min = distance;
			
			ans = tmp;
			
			
		}
			
	}
	
	if(judge==false) return false;
	
//	cout<<"Min "<<Min<<endl;
	
	newX = ans.x;
	newY = ans.y;
	
//	cout<<"newX "<<newX<<"  newY  "<<newY<<endl;
	
	return true;
}

bool attack(int newX,int newY){
	
	// 发动进攻可能 会导致 此次的 狂热者 死亡, 或者 之前出现在场地的 虫子 死亡
	// 虫子可能 死 多个 
	
	// newX newY atk r
	
	bool flag = true;
	int len = bugs.size();
	
	for(int i=0;i<len;i++){
		
		bug tmp = bugs[i];
		
		if(tmp.h<=0) continue; 
		
			long long distance = (long long) ( (long long) (newX-tmp.x) * (newX-tmp.x) + (long long) (newY-tmp.y) * (newY-tmp.y) );
		
		// 在攻击范围内的 bug 将受到 旋风斩的 冲击 
		if(distance <= ( (long long) r) *(long long) r){
			
			tmp.h-=3*atk;
			
			if(tmp.h<=0){
				
				bugs[i].h-=3*atk;
			} 
			else{
				
				 flag = false;
				 bugs[i].h-=3*atk;
			}
			
		}
			
	}
	
	return flag;
}

int main(){

	 ios::sync_with_stdio(false);
	 cin.tie(0),cout.tie(0);
	cin>>n;
	
	ans.resize(n);
	
	for(int i=0;i<n;i++){
		
		cin>>k>>x>>y;
		
		if(k==1){
			
			cin>>h;
			
			bugs.push_back( bug(i,x,y,h) );
			
			
		}else if(k==2){
			
			cin>>atk>>r;
			
			// 得到落地点 
			int newX=x,newY=y;
			bool flag1 = getPoint(newX,newY);
			
//			cout<<newX<<"  "<<newY<<endl;//----------------------
			
			if(flag1==false){
				
				// 说明没有虫子  原地放技能,且活到最后 
				ans[i]=true;
//				cout<<true<<"dsafasdf";//---------------------------
			}
			//进行攻击 
			else{
				// newX,newY
				bool flag = attack(newX,newY);
				
				// 有虫子 进行攻击,将攻击范围内的所有的虫子都 杀死,自己到最后也活着
				// 没杀死攻击范围内的所有的虫子  自己死 
				
				ans[i]=flag; 
//				cout<<flag;//-------------------------
			}
			
		}
		
	}
	
	// 判断 是 虫子的事件 中 虫子 是死是活
	int len = bugs.size();
	for(int i=0;i<len;i++){
		
		bug tmp = bugs[i];
		
		if(tmp.h<=0){
			
			ans[ tmp.id ] = false;
			
//			cout<<false<<endl;
		}else{
			
			ans[ tmp.id ] = true;
			
//			cout<<true<<endl;
		}
		
		
	}
	
	len = ans.size();
	for(int i=0;i<len;i++){
		
		if(ans[i]) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}

	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值