博客
关于我
牛牛与跷跷板
阅读量:386 次
发布时间:2019-03-05

本文共 2653 字,大约阅读时间需要 8 分钟。

为了解决这个问题,我们需要找到从起点到终点的最小跳跃次数。跳跃规则是只能从同一行或者同一列的下一行跃过去。我们可以使用广度优先搜索(BFS)来解决这个问题,因为BFS适合寻找最短路径的问题。

方法思路

  • 读取输入并初始化数据:首先读取输入数据,建立每个板块的位置信息,包括它在哪一行,左边界和右边界。
  • 排序板块:将所有板块按照从上到下的顺序排列,如果同一行的话,从左到右排列。
  • 建立图的边
    • 同一行的连通区域:对于每个板块k,直接与其右边的板块k+1连通。
    • 同一列的下一行的连通区域:对于每个板块k,找到下一行的连通区域,并与该区域的左右边界点连通。
  • 广度优先搜索(BFS):从起点开始,逐层扩展,找到到达终点的最短路径。
  • 解决代码

    #include 
    using namespace std;typedef long long ll;queue
    q;int tot = 0, s = -1, z = -1;int head[100010], dis[100010];struct ban { int l, r, p, y; } a[100010];struct ty { int next, t; } edge[2000010];void bfs() { dis[s] = 1; q.push(s); while (!q.empty()) { int x = q.front(); q.pop(); for (int i = head[x]; i != -1; i = edge[i].next) { int y = edge[i].t; if (dis[y] == -1) { dis[y] = dis[x] + 1; q.push(y); } } }}bool cmp(const ban &a, const ban &b) { if (a.y != b.y) return a.y < b.y; return a.l < b.l;}int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n = 0; cin >> n; for (int i = 1; i <= n; ++i) { a[i].y = 0, a[i].l = 0, a[i].r = 0; cin >> a[i].y >> a[i].l >> a[i].r; a[i].p = i; } sort(a + 1, a + n + 1, cmp); for (int i = 1; i <= n; ++i) { cout << a[i].p << " "; } int l = 1, r = 1; for (int i = 1; i <= n; ++i) { if (a[i].y == a[i + 1].y && a[i].r == a[i + 1].l) { edge[tot].next = head[i]; edge[tot].t = i; head[i] = tot++; edge[tot].next = head[i + 1]; edge[tot].t = i + 1; head[i + 1] = tot++; } } for (int i = 1; i <= n; ++i) { int current_y = a[i].y; int current_l = a[i].l; int current_r = a[i].r; l = max(current_l, 1); r = current_r; while (l <= r) { if (a[l].y != current_y) { l++; continue; } if (a[l].l > current_r) { break; } if (a[l].r < current_l) { l++; continue; } edge[tot].next = head[i]; edge[tot].t = l; head[i] = tot++; edge[tot].next = head[i]; edge[tot].t = r; head[i] = tot++; } if (l > 1) l--; } for (int i = 1; i <= n; ++i) { if (a[i].p == n) { s = i; z = i; } } bfs(); cout << dis[z] - 1 << endl;}

    代码解释

  • 读取输入和初始化数据:读取输入数据并初始化每个板块的位置信息。
  • 排序板块:按照从上到下的顺序排列,如果同一行则从左到右排列。
  • 建立图的边
    • 同一行的连通区域:处理同一行的连通区域,直接连接相邻的板块。
    • 同一列的下一行的连通区域:使用贪心方法,找到下一行的连通区域,并连接左右边界点。
  • 广度优先搜索(BFS):从起点开始,逐层扩展,找到到达终点的最短路径,并输出结果。
  • 转载地址:http://qpxwz.baihongyu.com/

    你可能感兴趣的文章
    Navicat for MySQL 命令列 执行SQL语句 历史日志
    查看>>
    Navicat for MySQL 查看BLOB字段内容
    查看>>
    Navicat for MySQL笔记1
    查看>>
    Navicat for MySQL(Ubuntu)过期解决方法
    查看>>
    Navicat Premium 12 卸载和注册表的删除
    查看>>
    Navicat 导入sql文件
    查看>>
    navicat 添加外键1215错误
    查看>>
    navicat 系列软件一点击菜单栏就闪退
    查看>>
    navicat 自动关闭_干掉Navicat!MySQL官方客户端到底行不行?
    查看>>
    Navicat 设置时间默认值(当前最新时间)
    查看>>
    navicat 连接远程mysql
    查看>>
    navicat:2013-Lost connection to MySQL server at ‘reading initial communication packet解决方法
    查看>>
    Navicate for mysql 数据库设计-数据库分析
    查看>>
    Navicat下载和破解以及使用
    查看>>
    Navicat中怎样将SQLServer的表复制到MySql中
    查看>>
    navicat创建连接 2002-can‘t connect to server on localhost(10061)且mysql服务已启动问题
    查看>>
    Navicat可视化界面导入SQL文件生成数据库表
    查看>>
    Navicat向sqlserver中插入数据时提示:当 IDENTITY_INSERT 设置为 OFF 时,不能向表中的标识列插入显式值
    查看>>
    Navicat因导入的sql文件中时间数据类型有参数而报错的原因(例:datetime(3))
    查看>>
    Navicat如何连接MySQL
    查看>>