abc 246 e 题解

abc 246 e

AT 链接

洛谷链接

题意#

有一个 N×N 的棋盘,(i,j) 表示棋盘第 i 行第 j 列的格子,行编号和列编号都是 1,2,,N

棋盘用 N 个长度为 N 的字符串 Si 描述:

  • 如果 Si,j= .,则格子 (i,j) 是空的。

  • 否则,格子 (i,j) 有障碍。

一开始格子 (Ax,Ay) 放了一颗棋子。在每次移动中,棋子可以朝某个对角线(某个斜 45 度方向)行走若干步后停下。棋子不能走出棋盘范围,并且该次移动的路径中不能包含障碍格子。

请你求出棋子从 (Ax,Ay) 走到 (Bx,By) 所需的最少移动次数。如果无法移动到 (Bx,By),输出 -1

2N1500

1Ax,Ay,Bx,ByN

(Ax,Ay)(Bx,By)

思路#

很明显,这题求最短路,是广搜。

但是,这个移动方式很让人头疼,每次到底挪动几次呢?

如果每次都去枚举移动的步数,时间复杂度又变成了 O(n3),会超时。

那么,我们应该怎么解决呢?

其实,每次只用走一步,但是,我们每次需要记录是往哪个方向走的。

如果当前走的方向和转移来的那个状态的转移方向是不同的,就需要多一次操作,否则,就还是这次操作。

因为每次转移有可能增加操作次数,有可能不增加,所以是 0-1 BFS,用双端队列维护。

#include <bits/stdc++.h>

using namespace std;

const int N = 1510;

const int dx[] = {1, 1, -1, -1};
const int dy[] = {1, -1, 1, -1};

int n, sx, sy, fx, fy, d[N][N][4];
char c[N][N];

struct Node {
  int x, y, dir;  // dir 表示方向
};

deque<Node> que;

void Record(int x, int y, int dis, int dir, int nowd) {
  if (x < 1 || x > n || y < 1 || y > n || c[x][y] == '#' || d[x][y][nowd] <= dis + (nowd != dir)) {
    return ;
  }
  d[x][y][nowd] = dis;
  if (nowd == dir) {
    que.push_front({x, y, nowd});
  } else {
    d[x][y][nowd]++;
    que.push_back({x, y, nowd});
  }
}

void bfs() {
  for (Record(sx, sy, 0, 4, 4); !que.empty(); ) {
    Node u = que.front();
    que.pop_front();
    for (int i = 0; i < 4; i++) {  // 转移
      Record(u.x + dx[i], u.y + dy[i], d[u.x][u.y][u.dir], u.dir, i);
    }
  }
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> n >> sx >> sy >> fx >> fy;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      cin >> c[i][j];
      d[i][j][0] = d[i][j][1] = d[i][j][2] = d[i][j][3] = 1e9;  // 初始化
    }
  }
  bfs();
  int ans = 1e9;
  for (int i = 0; i < 4; i++) {
    if (d[fx][fy][i] != 1e9) {
      ans = min(ans, d[fx][fy][i]);
    }
  }
  cout << (ans == 1e9 ? -1 : ans);
  return 0;
}

作者:cn

出处:https://www.cnblogs.com/chengning0909/p/18422866

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   chengning0909  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
历史上的今天:
2023-09-20 线性代数
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示