当前位置: 首页 > news >正文

计蒜客43467 Canyon Crossing(二分答案+多队列bfs)

题目链接
在这里插入图片描述
1.题目大意:给出一个r行c列的棋盘,现在需要从第r行走到第1行,现在能再走的路线上最多建k座桥(建一座桥相当于覆盖掉路线上的一个点),问满足条件的路径最小的最大值

2.首先只看“最小的最大值”这一明显的条件,便知道应该二分答案。不难看出,答案的上界是整个棋盘元素的最大值,下界为0。那么下一步,很明显应该是搜索,如果暴力的话,对第r行所有的点都按照前面二分的答案,求k+1次bfs,显然时间复杂度太高,怎么优化呢?对于当前走过的点,向后走的路径具有一个递推的关系,因为如果能在当前答案下建t座桥,那么就继续走下去,直到需要继续建桥,那么就将路线设置为建t+1座桥的路线。简单来说,就是设置k+1个队列,分别存代表建[0,k]座桥时需要走过的节点,如果某节点大于等于当前答案,那么无论在哪个队列都没有影响,否则就将节点push到下一个队列,即需要多建一座桥才能走的队列

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=1005;
typedef pair<int,int> P;
int G[maxn][maxn];
bool vis[maxn][maxn];
int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
int r,c,k;

bool bfs(int cur){
    memset(vis,0,sizeof vis);
    queue<P> q[k+10];
    for(int i=1;i<=c;i++){
        vis[r][i]=1;
        q[G[r][i]<cur?1:0].push(make_pair(r,i));   //第一次将所有起点判断是不需建桥就能走还是建1座桥能走,入队
    }
    for(int i=0;i<=k;i++){
        while(!q[i].empty()){
            P u=q[i].front(); q[i].pop();
            if(u.first==1) return 1;
            for(int j=0;j<4;j++){
                int x=u.first+dx[j];
                int y=u.second+dy[j];
                if(x<1 || x>=r || y<1 || y>c) continue; //因为已经判断第r行的所有起点,因此这里是大于等于r,条件不能写错否则WA
                if(!vis[x][y]){
                    vis[x][y]=1;
                    q[G[x][y]<cur?i+1:i].push(make_pair(x,y));  //原理同起点
                }
            }
        }
    }
    return 0;
}

int main()
{
    scanf("%d%d%d",&r,&c,&k);
    int L=0,R=0;
    for(int i=1;i<=r;i++)
    for(int j=1;j<=c;j++){
        scanf("%d",&G[i][j]);
        R=max(R,G[i][j]);
    }
    int ans=0;
    for(int i=1;i<=100;i++){
        int mid=(L+R)>>1;
        if(bfs(mid)){
            ans=mid;
            L=mid+1;
        }else R=mid-1;
    }
    printf("%d\n",ans);
    return 0;
}

相关文章:

  • 三句代码调整进程优先级
  • UVa714 Copying Books(二分答案+贪心)
  • 《程序员羊皮卷》成为电子工业出版社本周重点推荐图书
  • UVa12627 Erratic Expansion(递归/找规律)
  • 《金牌网管师》——10年的沉淀,18年的积累
  • 2020 CodeJam Round 1A
  • 如何更换Android模拟器界面
  • 2019 ICPC Latin American Regional Contests 计蒜客重现
  • youtube weburl后缀
  • UVa12174 Shuffle(滑动窗口)
  • Android开发指南-工具-画九宫格
  • UVa1608 Non-boring sequences(尺取+分治)
  • 通过枚举窗口获得窗口句柄名字并重命名窗口
  • “Shopee杯” e起来编程暨WHU2020校赛热身赛
  • CSDN BLOG EXPERT
  • 时间复杂度分析经典问题——最大子序列和
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 3.7、@ResponseBody 和 @RestController
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • create-react-app项目添加less配置
  • es6--symbol
  • export和import的用法总结
  • java 多线程基础, 我觉得还是有必要看看的
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • Netty源码解析1-Buffer
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • React的组件模式
  • Vue 2.3、2.4 知识点小结
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 关于字符编码你应该知道的事情
  • 基于webpack 的 vue 多页架构
  • 漂亮刷新控件-iOS
  • 前端面试之闭包
  • 如何正确配置 Ubuntu 14.04 服务器?
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #1014 : Trie树
  • #Linux(帮助手册)
  • #LLM入门|Prompt#3.3_存储_Memory
  • ( 10 )MySQL中的外键
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (libusb) usb口自动刷新
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (三十五)大数据实战——Superset可视化平台搭建
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转)IOS中获取各种文件的目录路径的方法
  • ***原理与防范
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net core 依赖注入的基本用发
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET开源项目介绍及资源推荐:数据持久层
  • [145] 二叉树的后序遍历 js
  • [AIR] NativeExtension在IOS下的开发实例 --- IOS项目的创建 (一)
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured
  • [BROADCASTING]tensor的扩散机制