(二分)730. 机器人跳跃问题

目录

题目链接

一些话

        切入点 

流程

套路

ac代码


题目链接

AcWing 730. 机器人跳跃问题 - AcWing


一些话


// 这里我用了浮点二分,mid = (l + r) / 2,最后再手动写了个向上取整的句子,所以没有wa,可能是题目数据太弱。
 


切入点 

游戏目标是到达第 N个建筑,在这个过程中能量值不能为负数个单位。

现在的问题是机器人至少以多少能量值开始游戏,才可以保证成功完成游戏?

机器人在满足条件的情况下能通过的建筑数量与初始能量值正相关,符合二分特性


流程

//二分check部分是个小模拟,按照模拟步骤写伪代码,然后等价替换

// 递推,枚举每一个台阶,然后对mid操作,每次操作后判断mid是否跳出了0~1e5的区间,小于0return false,大于0return true;
    // 枚举结束了后return true;

等价替换后的伪代码: 


// 写check函数伪代码(流程)的时候可以发现,不管mid和f[i]的大小关系如何,最终都是mid = 2 * mid - f[i];
// 因此写代码时就不用再分情况讨论,只要写一个mid = 2 * mid - f[i] 就可以了,然后还有一个剪枝操作,
// 因为f[i]max = 1e5,所以只要mid>1e5,直接return true就可以了

   

输出一个整数,表示所需的最少单位的初始能量值上取整后的结果。

这个我是真无语了,一直纠结yxc代码哪里用了向上取整,其实这道题不用浮点二分的话得到的答案肯定是大于浮点二分的精确小数答案的,所以用整数二分本身就是一个向上取整了


套路

二分的取整

①向上取整 mid的表示要写成

if(merge[mid] < x) l = mid + 1对应的写法

②向下取整

if(merge[mid] > x) r = mid - 1对应的写法

 merge是将mid转为mid对应的x值的函数

比如数组指针转值

题目条件与对应答案


ac代码

// 11:11 ~11:14读题
// ~24 ac
// 向上取整 mid的表示要写成l + r + 1 >> 1即可,向下取整 mid = l + r >> 1
// 这里我用了浮点二分,mid = (l + r) / 2,最后再手动写了个向上取整的句子,所以没有wa,可能是题目数据太弱。
// 已经申请了加强数据了

//二分check部分是个小模拟,按照模拟步骤写伪代码,然后等价替换
// 写check函数伪代码(流程)的时候可以发现,不管mid和f[i]的大小关系如何,最终都是mid = 2 * mid - f[i];
// 因此写代码时就不用再分情况讨论,只要写一个mid = 2 * mid - f[i] 就可以了,然后还有一个剪枝操作,
// 因为f[i]max = 1e5,所以只要mid>1e5,直接return true就可以了
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 1e5 + 10;
double f[N],n,maxn;
bool check(double mid){
    
    // 递推,枚举每一个台阶,然后对mid操作,每次操作后判断mid是否跳出了0~1e5的区间,小于0return false,大于0return true;
    // 枚举结束了后return true;
    // 可推导出mid = 2 * mid - f[i];
    // 
    for(int i = 1;i <= n;i++){
        if(mid >= f[i]) mid += mid - f[i];
        else mid -= (f[i] - mid);
        if(mid < 0) return false;
    }
    return true;
}
int main(){
    cin >> n;
    
    for(int i = 1;i <= n;i++) {
        scanf("%lf",&f[i]);
        maxn = max(f[i],maxn);
    }
    double l =  1,r = maxn;
    while(r - l > 1e-3){
        double mid = (l + r) / 2;
        if(check(mid)) r = mid;
        else l = mid;
    }
    if(int(l * 10) % 10) l += 1;
    cout << (int)l << endl;
    return 0;
}


我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草   ,又          ~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦! 字~数~啦!我草   ,又          ~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦! 字~数~啦!我草   ,又          ~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦! 字~数~啦!我草   ,又          ~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦! 字~数~啦!我草   ,又          ~在~水~字~数~啦!我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦! 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值