ABC 246 | E - Bishop 2
题目描述
给定一个\(N \times N\)的棋盘,以.表示空位置,以#表示障碍。给定起始位置和结束位置,问按照题目规定走法,最少可以多少步由起点到终点,若不可到达,输出-1。
题目规定走法:
- 可以按照以下四个方向一直走,直到不能走为止,以上行为算作
1步,即在该过程中走过的每个格子所用步数相同。 - 规定四个方向为左上、右上、左下、右下
数据范围
\(2 \le N \le 1500\)
题解
该题是一个典型的bfs题,只需按照题目所示方向以及步数计算方法更新dist数组,计算\(1500 * 1500 \approx 2 \times 10^6\),但实际测评发现tle,因此需要剪枝。
此处用到的剪枝方法是只要找到了\(dist[edx][edy]\),则直接return。
另外在写代码的时候漏写了一个判断条件,导致while(true)无法停止,需注意。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> pii;
const int N = 2010;
char a[N][N];
int n, stx, sty, edx, edy;
int dist[N][N];
int dx[4] = {1, 1, -1, -1}, dy[4] = {1, -1, 1, -1};
int bfs(){
memset(dist, 0x3f, sizeof dist);
dist[stx][sty] = 0;
queue<pii> q;
q.push({stx, sty});
while(q.size()){
auto t = q.front();
q.pop();
int tx = t.first, ty = t.second;
for(int i = 0; i < 4; i ++){
int k = 1;
while(true){
int x = tx + k * dx[i], y = ty + k * dy[i];
if(x > n || x < 1 || y > n || y < 1) break;
if(a[x][y] == '#') break;
if(dist[x][y] <= dist[tx][ty]) break; //不要漏写该条件
if(dist[x][y] > dist[tx][ty] + 1){
q.push({x, y});
dist[x][y] = dist[tx][ty] + 1;
}
if(x == edx && y == edy) return dist[edx][edy];
k ++;
}
}
}
return dist[edx][edy];
}
int main()
{
scanf("%d%d%d%d%d", &n, &stx, &sty, &edx, &edy);
for(int i = 1; i <= n; i ++) scanf("%s", a[i] + 1);
int ans = bfs();
if(ans == 0x3f3f3f3f) printf("-1\n");
else printf("%d\n", ans);
return 0;
}

浙公网安备 33010602011771号