hdu3533红蓝大战(广搜)

The students of the HEU are maneuvering for their military training.
The red army and the blue army are at war today. The blue army finds that Little A is the spy of the red army, so Little A has to escape from the headquarters of the blue army to that of the red army. The battle field is a rectangle of size m*n, and the headquarters of the blue army and the red army are placed at (0, 0) and (m, n), respectively, which means that Little A will go from (0, 0) to (m, n). The picture below denotes the shape of the battle field and the notation of directions that we will use later.

The blue army is eager to revenge, so it tries its best to kill Little A during his escape. The blue army places many castles, which will shoot to a fixed direction periodically. It costs Little A one unit of energy per second, whether he moves or not. If he uses up all his energy or gets shot at sometime, then he fails. Little A can move north, south, east or west, one unit per second. Note he may stay at times in order not to be shot.
To simplify the problem, let’s assume that Little A cannot stop in the middle of a second. He will neither get shot nor block the bullet during his move, which means that a bullet can only kill Little A at positions with integer coordinates. Consider the example below. The bullet moves from (0, 3) to (0, 0) at the speed of 3 units per second, and Little A moves from (0, 0) to (0, 1) at the speed of 1 unit per second. Then Little A is not killed. But if the bullet moves 2 units per second in the above example, Little A will be killed at (0, 1).
Now, please tell Little A whether he can escape.
Input
For every test case, the first line has four integers, m, n, k and d (2<=m, n<=100, 0<=k<=100, m+ n<=d<=1000). m and n are the size of the battle ground, k is the number of castles and d is the units of energy Little A initially has. The next k lines describe the castles each. Each line contains a character c and four integers, t, v, x and y. Here c is ‘N’, ‘S’, ‘E’ or ‘W’ giving the direction to which the castle shoots, t is the period, v is the velocity of the bullets shot (i.e. units passed per second), and (x, y) is the location of the castle. Here we suppose that if a castle is shot by other castles, it will block others’ shots but will NOT be destroyed. And two bullets will pass each other without affecting their directions and velocities.
All castles begin to shoot when Little A starts to escape.
Proceed to the end of file.
Output
If Little A can escape, print the minimum time required in seconds on a single line. Otherwise print “Bad luck!” without quotes.
Sample Input
4 4 3 10
N 1 1 1 1
W 1 1 3 2
W 2 1 2 4
4 4 3 10
N 1 1 1 1
W 1 1 3 2
W 1 1 2 4
Sample Output
9
Bad luck!

题意:每走一步就消耗一点精力(注意下一步可以选择不动,不动也消耗时间),在消耗完精力前(含刚好到)即成功,输出所用时间。
小A走到某个点时,刚好有子弹也落到这个点时,小A死亡。
炮塔会挡住子弹。
题解:每一步都要判断能不能存活,不能说明这一步不能走,当没法走动或到达目的地时结束。同时间到达同地点只取一个。

ac代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <math.h>
#include <cstdlib>
#include <queue>
#include<iomanip>
using namespace std;
int s1[5] = { 0,0,0,1,-1 }, s2[5] = { 0,-1,1,0,0 },s[105][105];
bool vist[105][105][1005];//一开始用整数型一直超内存,算了一下,已经1000万了,用int会多几万kb,所以必须用bool类型。
int judge,m,n,d,kkk;
struct asd
{
	char c;
	int v, t;
}pao[105][105];
struct node
{
	int x, y, time;
};
void bfs()
{
	int biao=0,p1,p2,p3,yu;
	queue<node>q;
	node a,next;
	a.x = a.y = a.time = 0;
	q.push(a);
	vist[0][0][0] = true;//特点时间特点地点只访问一次,标记。
	while (!q.empty())
	{
		a = q.front();
		q.pop();
		if (a.x == m && a.y == n) {
			judge = 0; cout << a.time << endl; return;
		}
		for (int i = 0; i < 5; i++)
		{
			p1 = next.x = a.x + s1[i];
			p2 = next.y = a.y + s2[i];
			p3 = next.time = a.time + 1;

			if (p3 > d)
				break;
			if (p1<0 || p2<0 || p1>m || p2>n)
				continue;
		
			if (!vist[p1][p2][p3]&&!s[p1][p2])
			{
				kkk = 1;
				for (int j = p1 - 1; j >= 0; j--)
				{
					if (s[j][p2] && pao[j][p2].c == 'S')
					{
						yu = p1 - j;//人离炮塔的距离
						if (yu%pao[j][p2].v)break;//不能整除说明子弹一定不会刚好落在该点,所以人没事
						if ((p3 - (yu / pao[j][p2].v)) < 0)break;//小于零说明人到达那个点,该炮塔的第一颗子弹还没到那个点,安全
						if ((p3 - (yu / pao[j][p2].v)) % pao[j][p2].t == 0) {
							kkk = 0; break;
						}//该炮塔的第一颗子弹到达那个点后,会周期性的(即t)有子弹射过来。


					}
					else if (s[j][p2])break;//前面有炮塔但射的方向不是向人,会为人在挡住该方向的子弹,所以人安全。

				}if (!kkk)continue;//人死了,那这个时间到这个点就不行了,不必判断其他方向的炮塔了。其他的跟这个方向的道理一样,不再解释。

				for (int j = p1 + 1; j <= m; j++)
				{
					if (s[j][p2] && pao[j][p2].c == 'N')
					{
						yu = j - p1;
						if (yu%pao[j][p2].v)break;
						if ((p3 - (yu / pao[j][p2].v)) < 0)break;
						if ((p3 - (yu / pao[j][p2].v)) % pao[j][p2].t == 0) {
							kkk = 0; break;
						}


					}
					else if (s[j][p2])break;

				}if (!kkk)continue;
				for (int j = p2 - 1; j >= 0; j--)
				{
					if (s[p1][j] && pao[p1][j].c == 'E')
					{
						yu = p2 - j;
						if (yu%pao[p1][j].v)break;
						if ((p3 - (yu / pao[p1][j].v)) < 0)break;
						if ((p3 - (yu / pao[p1][j].v)) % pao[p1][j].t == 0) {
							kkk = 0; break;
						}


					}
					else if (s[p1][j])break;

				}if (!kkk)continue;

				for (int j = p2 + 1; j <= n; j++)
				{
					if (s[p1][j] && pao[p1][j].c == 'W')
					{
						yu = j - p2;
						if (yu%pao[p1][j].v)break;
						if ((p3 - (yu / pao[p1][j].v)) < 0)break;
						if ((p3 - (yu / pao[p1][j].v)) % pao[p1][j].t == 0) {
							kkk = 0; break;
						}


					}
					else if (s[p1][j])break;
				}if (!kkk)continue;
				vist[p1][p2][p3]=true;
				q.push(next);
			}
		}

	}
}

int main()
{
	char c;
	int  k,t,v,x,y;
	while (cin >> m >> n >> k >> d)
	{
		judge = 1;
		memset(vist, false, sizeof(vist));
		memset(s, 0,sizeof(s));
		for (int i = 0; i < k; i++)
		{
			cin >>c>>t >> v >> x >> y;
			pao[x][y].t = t;
			pao[x][y].v = v;
			pao[x][y].c = c;
			s[x][y] = 1;
		}bfs();
		if (judge)cout << "Bad luck!" << endl;
	}
	
}

猜你喜欢

转载自blog.csdn.net/weixin_43965698/article/details/87023517