不是很难的搜索 代码量有点大 细节要注意好 每次打代码量稍微大点的题细节就很容易出问题。
开一个标记三维 如果达到这的时间不同就可以重复这个点,炮弹的话就是每个点枚举四个方向的看有没有炮弹刚好在这就可以了
终点可能有炮弹,这个题因为可以在原地等待 那么在枚举四个方向的时候就可以加一个方向 这个方向就是0,0表示原地不动
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define LL long long
struct Castle
{
int t;
char dir;
int v;
}castle[1005];
struct pos
{
int x;
int y;
int t;
};
int dat[105][105];
int n, m, k, d;
int mov[5][2] = { 1,0,0,1,-1,0,0,-1,0,0 };
// vis[x][y][t]标记是否在t时刻到达过x,y
bool vis[105][105][1005];
bool NoJudgeGo(int mx, int my, int mtime, int dirx, int diry, char ch)
{
int tx = mx;
int ty = my;
// x轴
if (dirx != 0)
{
while (1)
{
tx += dirx;
if (tx<0 || tx>n)
return false;
// 出现炮塔
if (dat[tx][ty] != -1)
{
Castle tcas = castle[dat[tx][ty]];
if (tcas.dir == ch)
{
if (abs(mx - tx) % tcas.v == 0)
{
// 如果达到的时候第一颗炮弹还没到这
if (abs(mx - tx) / tcas.v>mtime)
return false;
// 我到这的时间减去第一个子弹到这的时间
int tem = mtime - abs(mx - tx) / tcas.v;
// 能整除表示现在有子弹在这
if (tem%tcas.t == 0)
return true;
return false;
}
return false;
}
return false;
}
}
}
// y轴
else
{
while (1)
{
ty += diry;
if (ty<0 || ty>m)
return false;
if (dat[tx][ty] != -1)
{
Castle tcas = castle[dat[tx][ty]];
if (tcas.dir == ch)
{
if (abs(my - ty) % tcas.v == 0)
{
if (abs(my - ty) / tcas.v>mtime)
return false;
// 我到这的时间减去第一个子弹到这的时间
int tem = mtime - abs(my - ty) / tcas.v;
// 能整除表示现在有子弹在这
if (tem%tcas.t == 0)
return true;
return false;
}
return false;
}
return false;
}
}
}
return false;
}
int bfs(int x, int y)
{
memset(vis, false, sizeof(vis));
queue<pos>q;
pos temp;
temp.x = 0;
temp.y = 0;
temp.t = 0;
q.push(temp);
while (!q.empty())
{
temp = q.front();
q.pop();
for (int i = 0; i<5; i++)
{
int tx = temp.x + mov[i][0];
int ty = temp.y + mov[i][1];
if (tx<0 || ty<0 || tx>n || ty>m || vis[tx][ty][temp.t + 1] || dat[tx][ty] != -1)
continue;
// 判断四周是否有朝向我发射的炮弹
if (NoJudgeGo(tx, ty, temp.t + 1, -1, 0, 'S') || NoJudgeGo(tx, ty, temp.t + 1, 1, 0, 'N') || NoJudgeGo(tx, ty, temp.t + 1, 0, -1, 'E') || NoJudgeGo(tx, ty, temp.t + 1, 0, 1, 'W'))
{
continue;
}
if (temp.t + 1>d)
break;
if (tx == n && ty == m)
{
return temp.t + 1;
}
pos intemp;
intemp.t = temp.t + 1;
intemp.x = tx;
intemp.y = ty;
vis[tx][ty][intemp.t] = true;
q.push(intemp);
}
}
return -1;
}
int main()
{
while (scanf("%d%d%d%d", &n, &m, &k, &d) != EOF)
{
memset(dat, -1, sizeof(dat));
int cas = 0;
for (int i = 0; i<k; i++)
{
getchar();
int x, y;
scanf("%c%d%d%d%d", &castle[cas].dir, &castle[i].t, &castle[cas].v, &x, &y);
dat[x][y] = cas++;
}
int ans = bfs(0, 0);
if (ans == -1)
printf("Bad luck!\n");
else
printf("%d\n", ans);
}
return 0;
}