ABC 246 | E - Bishop 2

题目描述

给定一个N×N的棋盘,以.表示空位置,以#表示障碍。给定起始位置和结束位置,问按照题目规定走法,最少可以多少步由起点到终点,若不可到达,输出-1
题目规定走法:

  • 可以按照以下四个方向一直走,直到不能走为止,以上行为算作1步,即在该过程中走过的每个格子所用步数相同。
  • 规定四个方向为左上、右上、左下、右下

数据范围

2N1500

题解

该题是一个典型的bfs题,只需按照题目所示方向以及步数计算方法更新dist数组,计算150015002×106,但实际测评发现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;
}

posted @   小菜珠的成长之路  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示