每日打卡(1/1) (补:昨天生病了)
传送门:点击打开链接
题目大意:
地图上有若干门大炮,每门大炮有个朝向,隔若干时间会发射一枚炮弹,炮弹有速度,只能停在格点上。问人从起点到终点,要求不被大炮打中,可以在某点停留不动,问到终点最少要多少时间;
题目思路:
由于这题数据是有一定问题的,在方向问题上面搞了很久,最后发现是题目的问题。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 105;
struct node{
int dir,x,y,t,v;
}E[1005];
bool vis[maxn][maxn][1005],map[maxn][maxn],hav[maxn][maxn][1005];//hav数组:x,y,t
int n,m,k,d;
int dir[5][2] = {0,1,0,-1,1,0,0,-1,0,0};
struct Node{
int x,y,tot;
};
void pre()//首先预处理,用三维数组hav模拟炮弹时空位置
{
memset(hav,0,sizeof(hav));
for(int i=0;i<k;i++)
{
for(int j=0;j<=d;j+=E[i].t)
{
for(int l=1;;l++)
{
int x = E[i].x+dir[E[i].dir][0]*l;
int y = E[i].y+dir[E[i].dir][1]*l;
if(x<0||x>n||y<0||y>m||map[x][y]) break;
if(l%E[i].v==0) {
hav[x][y][j+l/E[i].v] = true;
}
}
}
}
}
int bfs()//宽搜
{
queue<Node> q;
while(!q.empty()) q.pop();
memset(vis,0,sizeof(vis));
Node a;
a.x = 0;
a.y = 0;
a.tot = 0;
q.push(a);
vis[0][0][0] = 1;
while(!q.empty())
{
a = q.front();
q.pop();
if(a.tot>d) return -1;
if(a.x==n&&a.y==m)
return a.tot;
for(int i=0;i<5;i++)
{
Node next;
next.x = a.x+dir[i][0];
next.y = a.y+dir[i][1];
next.tot = a.tot+1;
if(next.x<0||next.y<0||next.x>n||next.y>m||vis[next.x][next.y][next.tot]||map[next.x][next.y]||hav[next.x][next.y][next.tot]) continue;
q.push(next);
vis[next.x][next.y][next.tot] = 1;
}
}
return -1;
}
int main()
{
while(scanf("%d%d%d%d",&n,&m,&k,&d)!=EOF)
{
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
char s;
for(int i=0;i<k;i++)
{
getchar();
scanf("%c",&s);
if(s=='N') E[i].dir = 0;
if(s=='S') E[i].dir = 1;
if(s=='E') E[i].dir = 2;
if(s=='W') E[i].dir = 3;
scanf("%d%d%d%d",&E[i].t,&E[i].v,&E[i].y,&E[i].x);
map[E[i].x][E[i].y] = 1;
}
pre();
int ans = bfs();
if(ans==-1) {
cout<<"Bad luck!"<<endl;
}
else {
cout<<ans<<endl;
}
}
return 0;
}