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

算法日记33:14届蓝桥C++B冶炼金属(二分答案)

一、题目:

在这里插入图片描述

二、题解:

1、思路解析:

1)首先我们可以发现题目的样例数量为( n < = 1000 n<=1000 n<=1000),因此我们可以考虑 O ( n ∗ l o g n ) O(n*log^n) O(nlogn)时间复杂度的算法

在这里插入图片描述

2)通过观察题目我们可以发现,要求我们求解答案的最小值与最大值,且答案拥有一定的单调性

3)因此我们的第一个思想是用二分答案求解

2、二分答案详细过程:

1)找变量关系,判断合法区间

  • 通过画图我们发现,当转化率 V V V不断增加时, b [ i ] b[i] b[i]的变化如下,虽然一整段 b [ i ] b[i] b[i]的值单调性,但是我们可以对其进行分段
    • 二分: a [ i ] / x < = b [ i ] a[i]/x<=b[i] a[i]/x<=b[i]的区间,求解最小值(蓝色区间)
    • 二分: a [ i ] / x > = b [ i ] a[i]/x>=b[i] a[i]/x>=b[i]的区间,求解最大值(红色区间)
      在这里插入图片描述

2)判断区间端点

1# 找最小值
  • 二分函数构建
    • 此时,我们发现其合法区间为 < = b [ i ] <=b[i] <=b[i](因为我们要使得我们想要求解的最值处于划分的区间边界)
    • 因此 我们可以通过判断 a [ i ] / x a[i]/x a[i]/x的值来判断是否合法(最后return r)
      在这里插入图片描述
//合法区间<=b[i]的值
bool check_min(ll x) //x表示当前的转化率
{
  for(ll i=1;i<=n;i++) 
  {
    if(a[i]/x>b[i]) return false;
  }
  return true;
}
  • 二分入口构建
    • check_min(mid)成立时,说明此时 a [ i ] / x < = b [ i ] a[i]/x<=b[i] a[i]/x<=b[i] m i d mid mid偏大,因此r=mid
    • 最后reutrn r即可(如图所示, r r r所指向的部分为答案)
  ll l = 1, r = 1e9 + 7;
  while(l+1<r)  //二分答案找最满足条件的最小值
  {
    ll mid=(l+r)>>1;
    if(check_min(mid))   r=mid; 
    else l=mid;
  }
  v_min=r;
2#找最大值
  • 二分函数构建
    • 此时,我们发现其合法区间为 > = b [ i ] >=b[i] >=b[i](因为我们要使得我们想要求解的最值处于划分的区间边界)
    • 因此 我们可以通过判断 a [ i ] / x a[i]/x a[i]/x的值来判断是否合法(最后return L)
      在这里插入图片描述
bool check_max(ll x) //合法区间>=b[i]的值
{
  for(ll i=1;i<=n;i++) 
  {
    if(a[i]/x<b[i]) return false;
  }
  return true;
}
  • 二分入口构建
    • check_min(mid)成立时,说明此时 a [ i ] / x > = b [ i ] a[i]/x>=b[i] a[i]/x>=b[i] m i d mid mid偏小,因此l=mid
    • 最后reutrn l即可(如图所示, l l l所指向的部分为答案)
 l=1,r=1e9+7;
  while(l+1<r)  //二分答案找满足条件的最大值
  {
    ll mid=(l+r)>>1;
    if(check_max(mid)) l=mid;
    else r=mid;
  }
  v_max=l;

3、完整代码解析:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 2e5 + 7;
ll a[N], b[N], n;

//合法区间<=b[i]的值
bool check_min(ll x) //x表示当前的转化率
{
  for(ll i=1;i<=n;i++) 
  {
    if(a[i]/x>b[i]) return false;
  }
  return true;
}

bool check_max(ll x) //合法区间>=b[i]的值
{
  for(ll i=1;i<=n;i++) 
  {
    if(a[i]/x<b[i]) return false;
  }
  return true;
}

int main() {
  cin >> n;
  ll v_min,v_max;

  for (int i = 1; i <= n; i++) 
  {
    cin >> a[i] >> b[i];
  }
  //转化率V->:不断增加        Vmin       Vmax
  //结果:>b[i] >b[i]  >b[i] =b[i] =b[i] =b[i]  <b[i] <b[i] <b[i]
  ll l = 1, r = 1e9 + 7;
  while(l+1<r)  //二分答案找最满足条件的最小值
  {
    ll mid=(l+r)>>1;
    if(check_min(mid))   r=mid; 
    else l=mid;
  }
  v_min=r;

  l=1,r=1e9+7;
  while(l+1<r)  //二分答案找满足条件的最大
  {
    ll mid=(l+r)>>1;
    if(check_max(mid)) l=mid;
    else r=mid;
  }
  v_max=l;

    
  cout << v_min << ' ' << v_max;
  return 0;
}

相关文章:

  • 10个实用IntelliJ IDEA插件
  • es 修改索引模板分词类型
  • 归并排序:分治哲学的完美演绎与时空平衡的艺术
  • 蓝桥杯算法——铠甲合体
  • FPGA有关HDMI的一些知识,程序源自bilibi正点原子
  • Spring Boot 3.0核心特性解读
  • vue 安装包时报错 Error: not found: python2
  • C++ 内存序在多线程中的使用
  • 扫雷雷雷雷雷【水文勿三】
  • 能简述一下动态 SQL 的执行原理吗
  • 信号与系统第二章学习(六)
  • 利用Python爬虫按图搜索1688商品(拍立淘)
  • 安装好pycharm后,双击pycharm,出现“无法找到入口”,怎么办?
  • 第3章:启动界面与主界面设计
  • 解锁前端表单数据的秘密旅程:从后端到用户选择!✨
  • 线程池项目优化
  • mapbox高阶,结合threejs(threebox)实现立体三维飞线图
  • 时尚创意品牌海报徽标设计无衬线英文字体安装包 Scribles – A Brush Font
  • Python 面向对象高级编程-定制类
  • 8.RabbitMQ队列详解
  • 如何做产品网站推广/湛江seo推广外包
  • 有什么做海报网站/建网站平台
  • 网站做收录是什么意思/跨境电商平台
  • 备案号是哪个网站/软文推广的优点
  • 大型网站搜索怎么做的/小红书外链管家
  • 从哪个网站找钢做的微商/长春网站建设推广