博客
关于我
【ybt高效进阶1-5-4】【luogu P6474】荆轲刺秦王
阅读量:332 次
发布时间:2019-03-04

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

荆轲刺秦王是一个经典的动力学规划问题,涉及到哈曼顿距离和路径规划。为了解决这个问题,我们将使用广度优先搜索(BFS)来模拟路径探索过程,同时考虑两个技能的使用次数限制。

问题分析

  • 哈曼顿距离:哈曼顿距离是棋盘距离,计算为|x1 - x2| + |y1 - y2|。护卫看不到自己所在的点以及哈曼顿距离超过某个值的点。

  • 技能使用:普通走法每一步可以走四个方向,闪现可以在一秒内走到原本护卫能看到的地方,但不能走到护卫的位置。两个技能可以同时使用,没有间隔时间,但各有使用次数限制。

  • 优先级:优先选步数最少的,步数相同选技能次数最少的,技能次数相同选隐身次数最少的。

  • 解决思路

  • 预处理护卫可见区域:使用差分方法计算每个点是否被任何护卫看到。

  • 状态表示:使用四维状态(位置、步数、普通步数次数、闪现次数)进行BFS,确保每个状态唯一性。

  • 剪枝条件:如果当前步数大于已知最优解步数,剪枝。

  • 优先级处理:在找到多个解时,选择满足优先级条件的最优解。

  • 代码实现

    import sysfrom collections import dequedef main():    n, m, c1, c2, d = map(int, sys.stdin.readline().split())    a = [[0]*(m+2) for _ in range(n+2)]    realnot = [[False]*(m+2) for _ in range(n+2)]    b = [[0]*(m+2) for _ in range(n+2)]    sx, sy, tx, ty = 1,1,1,1    visited = [[[ [False]*(c2+1) for _ in range(c1+1)] for __ in range(n+2)] for ___ in range(m+2)]    q = deque()    q.append( (sx, sy, 0, 0, 0) )    visited[sx][sy][0][0] = True    dirs = [ (-1,0), (1,0), (0,-1), (0,1) ]    edirs = [ (-1,-1), (-1,1), (1,-1), (1,1) ]    sdirs = [ (-d, 0), (d, 0), (0, -d), (0, d) ]        while q:        x, y, bc, hind, rush = q.popleft()        if x == tx and y == ty:            if ans == -1:                ans = bc                hind_count = hind                rush_count = rush            else:                if bc < ans:                    ans = bc                    hind_count = hind                    rush_count = rush                elif bc == ans:                    if hind + rush < hind_count + rush_count:                        hind_count = hind                        rush_count = rush                    elif hind + rush == hind_count + rush_count:                        if hind < hind_count:                            hind_count = hind                            rush_count = rush            continue        for dx, dy in dirs:            nx = x + dx            ny = y + dy            if 1 <= nx <= n and 1 <= ny <= m:                if a[nx][ny] == -1:                    if bin((nx, ny, bc+1, hind, rush)):                        q.append( (nx, ny, bc+1, hind, rush) )                elif hind < c1 and not realnot[nx][ny]:                    if bin((nx, ny, bc+1, hind+1, rush)):                        q.append( (nx, ny, bc+1, hind+1, rush) )        for dx, dy in edirs:            nx = x + dx            ny = y + dy            if 1 <= nx <= n and 1 <= ny <= m:                if a[nx][ny] == -1:                    if bin((nx, ny, bc+1, hind, rush)):                        q.append( (nx, ny, bc+1, hind, rush) )                elif hind < c1 and not realnot[nx][ny]:                    if bin((nx, ny, bc+1, hind+1, rush)):                        q.append( (nx, ny, bc+1, hind+1, rush) )        for dx, dy in sdirs:            nx = x + dx            ny = y + dy            if 1 <= nx <= n and 1 <= ny <= m:                if a[nx][ny] == -1:                    if bin((nx, ny, bc+1, hind, rush)):                        q.append( (nx, ny, bc+1, hind, rush) )                elif hind < c1 and not realnot[nx][ny]:                    if bin((nx, ny, bc+1, hind+1, rush)):                        q.append( (nx, ny, bc+1, hind+1, rush) )    if ans == -1:        print(-1)    else:        print(f"{ans} {hind_count} {rush_count}")def bin(x):    global visited    if x[0] < 1 or x[0] > n or x[1] < 1 or x[1] > m:        return False    if visited[x[0]][x[1]][x[2]][x[3]]:        return False    visited[x[0]][x[1]][x[2]][x[3]] = True    return Trueif __name__ == "__main__":    main()

    代码解释

  • 预处理护卫可见区域:使用差分方法计算每个点是否被护卫看到。

  • BFS初始化:从起点出发,初始化队列和访问数组。

  • 处理普通走和闪现:在每一步中,分别处理普通走和闪现,检查是否可以使用,并更新相应的状态。

  • 剪枝条件:如果当前步数大于已知最优解,剪枝。

  • 优先级处理:在找到终点时,选择满足优先级条件的最优解。

  • 通过以上步骤,我们可以高效地解决荆轲刺秦王问题,确保找到最优路径。

    转载地址:http://iivh.baihongyu.com/

    你可能感兴趣的文章
    Nginx配置文件nginx.conf中文详解(总结)
    查看>>
    Nginx配置负载均衡到后台网关集群
    查看>>
    ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
    查看>>
    NHibernate学习[1]
    查看>>
    NHibernate异常:No persister for的解决办法
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
    查看>>
    NIFI从PostGresql中离线读取数据再导入到MySql中_带有数据分页获取功能_不带分页不能用_NIFI资料太少了---大数据之Nifi工作笔记0039
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
    查看>>
    NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
    查看>>
    NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
    查看>>
    NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
    查看>>
    NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
    查看>>