带状态的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;
}
#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;
}
#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;
}