要求:人从(0,0)到(m,n),人有d个能量,每秒消耗一点能量,每秒可以上下左右走一格或待在原地不动。网格中会有炮台,炮台向上下左右的某个方向射击,每t秒射击一次,子弹速度为v米每秒。问人是否可以到达目的地,若可以,求最短时间。
方法:简单bfs
1.注意使用vis[x][y][time1]标记。
2.一直MLE是因为使用了int vis[105][105][1005],改成bool vis[105][105][1005]即可。
3.比原本的搜索方向多了一个原地不动的方向。
#include<iostream>
#include<stdio.h>
#include<queue>
#include<map>
#include<string.h>
#include<math.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std ;
int m , n , k , d ;
int row[5] = {-1 , 1 , 0 , 0 , 0} ;
int col[5] = {0 , 0 , -1 , 1 , 0} ;
int dire[105][105] ;
int tt[105][105] ;
int vv[105][105] ;
bool vis[105][105][1005] ;
struct node
{
int x , y ;
int time1 ;
};
queue<node>q ;
bool check(node a)
{
int i , j ;
int dis ;
if(a.x < 0 || a.x > m || a.y < 0 || a.y > n || dire[a.x][a.y] >= 0
|| vis[a.x][a.y][a.time1] == 1)
return 0 ;
for(i = a.x - 1 ; i >= 0 ; i --)
{
if(dire[i][a.y] >= 0)
{
if(dire[i][a.y] == 1)
{
dis = a.x - i ;
if(dis % vv[i][a.y] == 0
&&a.time1 >= dis / vv[i][a.y]
&&(a.time1 - dis / vv[i][a.y]) % tt[i][a.y] == 0)
return 0 ;
}
break ;
}
}
for(i = a.x + 1 ; i <= m ; i ++)
{
if(dire[i][a.y] >= 0)
{
if(dire[i][a.y] == 0)
{
dis = i - a.x ;
if(dis % vv[i][a.y] == 0
&&a.time1 >= dis / vv[i][a.y]
&&(a.time1 - dis / vv[i][a.y]) % tt[i][a.y] == 0)
return 0 ;
}
break ;
}
}
for(i = a.y - 1 ; i >= 0 ; i --)
{
if(dire[a.x][i] >= 0)
{
if(dire[a.x][i] == 3)
{
dis = a.y - i ;
if(dis % vv[a.x][i] == 0
&&a.time1 >= dis / vv[a.x][i]
&&(a.time1 - dis / vv[a.x][i]) % tt[a.x][i] == 0)
return 0 ;
}
break ;
}
}
for(i = a.y + 1 ; i <= n ; i ++)
{
if(dire[a.x][i] >= 0)
{
if(dire[a.x][i] == 2)
{
dis = i - a.y ;
if(dis % vv[a.x][i] == 0
&&a.time1 >= dis / vv[a.x][i]
&&(a.time1 - dis / vv[a.x][i]) % tt[a.x][i] == 0)
return 0 ;
}
break ;
}
}
return 1 ;
}
void bfs()
{
int i , j ;
node a , b ;
while(!q.empty())
q.pop() ;
a.x = 0 ;
a.y = 0 ;
a.time1 = 0 ;
q.push(a) ;
while(!q.empty())
{
a = q.front() ;
q.pop() ;
if(m - a.x + n - a.y > d - a.time1)
continue ;
if(a.time1 > d)
break ;
if(a.x == m && a.y == n)
{
printf("%d\n" , a.time1) ;
return ;
}
for(i = 0 ; i < 5 ; i ++)
{
b.x = a.x + row[i] ;
b.y = a.y + col[i] ;
b.time1 = a.time1 + 1 ;
if(check(b))
{
vis[b.x][b.y][b.time1] = 1 ;
q.push(b) ;
}
}
}
printf("Bad luck!\n") ;
}
int main()
{
int i ;
int t , v , x , y ;
char s[10] ;
while(scanf("%d%d%d%d" , &m , &n , &k , &d)!=EOF)
{
memset(dire , -1 , sizeof(dire)) ;
memset(vis , 0 , sizeof(vis)) ;
for(i = 0 ; i < k ; i ++)
{
scanf("%s" , &s) ;
scanf("%d%d%d%d" , &t , &v , &x , &y) ;
tt[x][y] = t ;
vv[x][y] = v ;
if(s[0] == 'N')
dire[x][y] = 0 ;
else if(s[0] == 'S')
dire[x][y] = 1 ;
else if(s[0] == 'W')
dire[x][y] = 2 ;
else
dire[x][y] = 3 ;
}
bfs() ;
}
}