TOJ 2870 ZOJ 3221 Lich / 广搜

Lich

时间限制(普通/Java):1000MS/3000MS     运行内存限制:65536KByte
 

描述

Dota is a kind of map in the famous game Warcraft 3. It 's so interesting that many ZJUers are fond of it. I am one of those happy guys.

Lich is one of the heroes that I would like to choose to use in the Dota game. He has the power to use frost to cause tremendous pain to his enemy. The Lich is a murderer without a trace of warmth. His most terrified skill is Chain Frost. When using it, the lich will release a jumping breath of frost that can bounce for a few times. Frost will randomly bounce back and forth between units that are within some range and cause some damage per hit.

When I use this hero, I always want to know: can I kill the enemy heroes by using this terminal skill. Though I am a computer science student, I am not good at programing. So I turn to you, the talented ACM player.

Suppose that the lich and the enemy hero(only one) stand in a two dimension map. There areN heroes in the map. The first hero is the lich and the last hero is the enemy hero. The lich can use Chain Frost only once. The Chain Frost will first hit the one which has a distance no more thanR from the lich and cause D damage. Then the frost will randomly bounce back and forth between alive units(but not lich himself) that are withinR range and cause D damage per hit. The frost will not bounce more thanK times.

Notice that the frost must bounce from one unit to the other, or it will stop. And when the Chain Frost hits some person A, the next time it must bounce to the other person alive B, and the distance between A and B must be no more than R, or it will stop too.

Every one have a health point(HP), and when one's health point is no more than 0, he is defeated. And when one is defeated he will be removed from the map and can't be hit by the frost any more.

输入

The first line is the num of cases T(0 <=T <= 300). Each test case starts with a line, which contains 4 positive integers,N R K D (3 <= N <= 1000, R K D <= 30000). Then N lines follow, each contain three non-negative integers:Xi, Yi, Hi (Xi Yi Hi <= 30000, Hi >= 1).Xi Yi is the horizontal coordinate and vertical coordinate and of the hero andHi is his health point.

There is a blank after each case. 

输出

For each case, just output one line. If it is possible for the lich to defeat the enemy hero, output "YES", else output "NO". Print one blank after each case.

样例输入

3
3 1 6 100
0 0 1200
0 1 300
0 2 300

3 1 5 100
0 0 1200
0 1 300
0 2 300

3 1 6 100
0 0 1200
0 1 200
0 2 300

样例输出

YES

NO

NO

首先广搜从1到n最短步数

然后可能会想第一次到n应该更新走过的点的hp 然后k(次数) 减去最短步数  应该攻击n的次数减一 再去考虑弹 这样很麻烦

不去更新hp 假设经过的还是没少血从n这个点再去弹射 k的次数再加2(有点难解释)特殊情况是一步就到了 这种情况 就k-1然后应该攻击的次数减一

表达能力有待提高

#include <stdio.h>
#include <vector>
#include <string.h>
#include <queue>
using namespace std;
const int MAX = 1010;
struct node
{
	int x;
	int y;
	int num;
	int hp;
	int step;

};
int n,r,k,d;
int dis[MAX];
bool map[MAX];
node a[MAX];
vector <int> v[MAX];

int dist(int x1,int y1,int x2,int y2)
{
	return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}
void bfs()
{
	int i;
	memset(map,false,sizeof(map));
	node p;
	p.num = 1;
	p.step = 0;
	queue <node> q;
	q.push(p);
	map[1] = true;
	while(!q.empty())
	{
		p = q.front();
		q.pop();
		a[p.num].step = p.step;
		int len = v[p.num].size();
		for(i = 0;i < len; i++)
		{
			int temp = v[p.num][i];
			if(map[temp])
				continue;
			node t;
			t.num = temp;
			map[temp] = true;
			t.step = p.step + 1;
			q.push(t);
		}	
	}
}
int main()
{
	int t,i,j,x,y,z;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d %d %d %d",&n,&r,&k,&d);
		for(i = 1;i <= n; i++)
		{
			a[i].step = 0;
			v[i].clear();
		}
		for(i = 1;i <= n; i++)
		{
			scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].hp);
			for(j = 1;j < i; j++)
			{
				if(dist(a[i].x,a[i].y,a[j].x,a[j].y) <= r*r)
				{
					v[i].push_back(j);
					v[j].push_back(i);
				}
			}
		}
		bfs();
		if(a[n].step == 0)
		{
			puts("NO\n");
			continue;
		}
		if(a[n].step == 1)
		{
			k--;
			a[n].hp -= d;
			if(a[n].hp <= 0)
			{
				puts("YES\n");
				continue;
				
			}
		}
		if(a[n].step >= 2)
			k = k - a[n].step + 2;
		int cnt1 = (a[n].hp + d - 1)/ d;
		if(cnt1 * 2 > k)
		{
			puts("NO\n");
			continue;
		}
		int cnt2 = 0;
		for(i = 0;i < v[n].size(); i++)
		{
			if(v[n][i] == 1)
				continue;
			cnt2 += (a[v[n][i]].hp + d - 1)/ d;
		}
		if(cnt2 < cnt1)
			puts("NO\n");
		else
			puts("YES\n");
			
	}
	return 0;
}


 

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页

打赏作者

芋智波佐助

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值