AcWing 1076. 迷宫问题
在求最短路的时候需要存储某个点是由哪个点更新过来的。
#include<iostream>
#include<cstring>
#define x first
#define y second
using namespace std;
const int N = 1005;
typedef pair<int,int> PII;
int g[N][N];
PII q[N*N];
PII pre[N][N];
int n;
int dx[4] = {0,-1,0,1}, dy[4] = {-1,0,1,0};
void bfs(int sx,int sy)
{
int hh=0,tt=0;
q[0] = {sx,sy};
memset(pre,-1,sizeof pre);
pre[sx][sy]={0,0};
while(hh <= tt)
{
PII t = q[hh++];
for(int i=0; i<4; i++)
{
int a = t.x + dx[i], b = t.y + dy[i];
if(a<0 || a>=n || b<0 || b>=n) continue;
if(g[a][b]) continue;
if(pre[a][b].x != -1) continue;
q[++tt] = {a,b};
pre[a][b] = t;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
scanf("%d",&g[i][j]);
bfs(n-1,n-1); //从最后一个点开始搜
PII end(0,0);
while(1)
{
printf("%d %d\n",end.x,end.y);
if(end.x == n - 1 && end.y == n - 1) break;
end = pre[end.x][end.y];//更新
}
}
AcWing 188. 武士风度的牛
这道题的不一样的地方在于它是按“日”字型方向来搜的。所以需把dx、dy数组写好。
如果黑色点是我们取出来的队头元素。那么图中的8个红色点就是可以拓展到的点。所以,dx、dy数组为:
int dx[8] = {-1,-2,-2,-1,1,2,2,1};
int dy[8] = {-2,-1,1,2,2,1,-1,-2};
#include<iostream>
#include<cstring>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
const int N = 155;
PII q[N*N];
char g[N][N];
int d[N][N];
int n,m;
int dx[8] = {-1,-2,-2,-1,1,2,2,1};
int dy[8] = {-2,-1,1,2,2,1,-1,-2};
int bfs(int sx,int sy)
{
int hh = 0, tt = 0;
memset(d,-1,sizeof d);
q[0] = {sx,sy};
d[sx][sy] = 0;
while(hh <= tt)
{
PII t = q[hh++];
for(int i=0; i<8; i++)
{
int a = t.x + dx[i], b = t.y + dy[i];
if(a<0 || a>=n || b<0 || b>=m) continue;
if(d[a][b] != -1) continue;
if(g[a][b] == '*') continue;
if(g[a][b] == 'H') return d[t.x][t.y] + 1;
q[++tt] = {a,b};
d[a][b] = d[t.x][t.y] + 1;
}
}
return 0;
}
int main()
{
cin >> m >> n;
for(int i=0; i<n; i++) cin >> g[i];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(g[i][j] == 'K')
cout << bfs(i,j);
return 0;
}
AcWing 1100. 抓住那头牛
待补…