带状态的BFS+优先队列。
大意:一艘船在海上航行,需要从海上的一点航行到海上的另一点,期间有八种不同方向的风吹过,如果是顺风航行的话,那么不需要消耗燃料,否则消耗燃料+1。
思路1:假如从A->B,那么将maze[Bx][By]与现在的方向i相比较,如果相等,则跳过。若不相等,则step++;之后我们有两种处理方法,一是用三维数组int v[SIZE][SIZE][8]判重,我试了试,果断MLE。改为char v[SIZE][SIZE][8],TLE。
思路2:判状态不用三维数组判重,而直接用Time[SIZE][SIZE]储存每一个状态的时间,如果q.step<Time[q.x][q.y]则更新,入队。
AC CODE:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
using
namespace std;
const
int SIZE =
2000;
const
int INF =
0x3f3f3f3f;
const
int dx[] = {-
1, -
1,
0,
1,
1,
1,
0, -
1};
const
int dy[] = {
0,
1,
1,
1,
0, -
1, -
1, -
1};
char maze[SIZE][SIZE];
int Time[SIZE][SIZE];
int n, m;
int bx, by, ex, ey;
struct node
{
int x, y, step;
friend
bool
operator< (
const node &a,
const node &b)
{
return a.step > b.step;
}
}p, q;
int check(
int x,
int y)
{
if(x >=
1 && x <= n && y >=
1 && y <= m)
return
1;
return
0;
}
void bfs()
{
priority_queue<node> Q;
p.x = bx; p.y = by; p.step =
0;
Time[bx][by] =
0;
Q.push(p);
while(!Q.empty())
{
p = Q.top();
Q.pop();
if(p.x == ex && p.y == ey)
{
return ;
}
for(
int i =
0; i <
8; i++)
{
q = p;
q.x += dx[i];
q.y += dy[i];
if(i != maze[p.x][p.y]-
'
0
') q.step++;
if(check(q.x, q.y) && q.step < Time[q.x][q.y])
{
Time[q.x][q.y] = q.step;
Q.push(q);
}
}
}
return ;
}
void init()
{
for(
int i =
1; i <= SIZE; i++)
{
for(
int j =
1; j <= SIZE; j++)
{
Time[i][j] = INF;
}
}
}
int main()
{
while(~scanf(
"
%d%d
", &n, &m))
{
getchar();
for(
int i =
1; i <= n; i++)
{
for(
int j =
1; j <= m ; j++)
{
scanf(
"
%c
", &maze[i][j]);
}
getchar();
}
int T;
scanf(
"
%d
", &T);
while(T--)
{
init();
scanf(
"
%d%d%d%d
", &bx, &by, &ex, &ey);
if(bx == ex && by == ey)
{
printf(
"
0\n
");
continue;
}
bfs();
printf(
"
%d\n
", Time[ex][ey]);
}
}
return
0;
}
TLE CODE:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
using
namespace std;
const
int SIZE =
1010;
const
int INF =
0x3f3f3f3f;
const
int dx[] = {-
1, -
1,
0,
1,
1,
1,
0, -
1};
const
int dy[] = {
0,
1,
1,
1,
0, -
1, -
1, -
1};
char maze[SIZE][SIZE];
char v[SIZE][SIZE][
8];
int n, m;
int bx, by, ex, ey;
struct node
{
int x, y, step;
friend
bool
operator< (
const node &a,
const node &b)
{
return a.step > b.step;
}
}p, q;
int check(
int x,
int y)
{
if(x >=
1 && x <= n && y >=
1 && y <= m)
return
1;
return
0;
}
int bfs()
{
priority_queue<node> Q;
p.x = bx; p.y = by; p.step =
0;
memset(v,
0,
sizeof(v));
v[bx][by][maze[bx][by]] =
1;
Q.push(p);
while(!Q.empty())
{
p = Q.top();
Q.pop();
if(p.x == ex && p.y == ey)
{
return q.step;
}
for(
int i =
0; i <
8; i++)
{
q = p;
q.x += dx[i];
q.y += dy[i];
if(i != maze[p.x][p.y]-
'
0
') ++q.step;
if(check(q.x, q.y) && !v[q.x][q.y][i])
{
v[q.x][q.y][i] =
1;
Q.push(q);
}
}
}
return -
1;
}
int main()
{
while(~scanf(
"
%d%d
", &n, &m))
{
getchar();
for(
int i =
1; i <= n; i++)
{
for(
int j =
1; j <= m ; j++)
{
scanf(
"
%c
", &maze[i][j]);
}
getchar();
}
int T;
scanf(
"
%d
", &T);
while(T--)
{
scanf(
"
%d%d%d%d
", &bx, &by, &ex, &ey);
if(bx == ex && by == ey)
{
printf(
"
0\n
");
continue;
}
int ans = bfs();
printf(
"
%d\n
", ans);
}
}
return
0;
}