C++前缀和算法的应用:最大化城市的最小供电站数目
本文涉及的基础知识点
C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频
二分法
题目
给你一个下标从 0 开始长度为 n 的整数数组 stations ,其中 stations[i] 表示第 i 座城市的供电站数目。
每个供电站可以在一定 范围 内给所有城市提供电力。换句话说,如果给定的范围是 r ,在城市 i 处的供电站可以给所有满足 |i - j| <= r 且 0 <= i, j <= n - 1 的城市 j 供电。
|x| 表示 x 的 绝对值 。比方说,|7 - 5| = 2 ,|3 - 10| = 7 。
一座城市的 电量 是所有能给它供电的供电站数目。
政府批准了可以额外建造 k 座供电站,你需要决定这些供电站分别应该建在哪里,这些供电站与已经存在的供电站有相同的供电范围。
给你两个整数 r 和 k ,如果以最优策略建造额外的发电站,返回所有城市中,最小供电站数目的最大值是多少。
这 k 座供电站可以建在多个城市。
示例 1:
输入:stations = [1,2,4,5,0], r = 1, k = 2
输出:5
解释:
最优方案之一是把 2 座供电站都建在城市 1 。
每座城市的供电站数目分别为 [1,4,4,5,0] 。
- 城市 0 的供电站数目为 1 + 4 = 5 。
- 城市 1 的供电站数目为 1 + 4 + 4 = 9 。
- 城市 2 的供电站数目为 4 + 4 + 5 = 13 。
- 城市 3 的供电站数目为 5 + 4 = 9 。
- 城市 4 的供电站数目为 5 + 0 = 5 。
供电站数目最少是 5 。
无法得到更优解,所以我们返回 5 。
示例 2:
输入:stations = [4,4,4,4], r = 0, k = 3
输出:4
解释:
无论如何安排,总有一座城市的供电站数目是 4 ,所以最优解是 4 。
参数范围:
n == stations.length
1 <= n <= 105
0 <= stations[i] <= 105
0 <= r <= n - 1
0 <= k <= 109
分析
时间复杂度
O(nlogm),m= sum(stations)+k。
第一层循环
如果任何城市的最小供电站数大于等于llTarget,则任何城市的最小供电站数一定llTarget-1,如果有多个满足条件的,我们返回最后一个。显然用左闭右开的二分。极限情况下能有多少供电站?所有供电站(已建和可建的)都可以供应所有城市。
第二层循环
当前城市供电站不足的时候,在right城市建立足够的供电站。
变量说明
| i | 当前城市 |
| llTarget | 让所有城市至少有iTarget个供电站 |
| llNeed | 让所有城市至少有iTarget个供电站,需要新建多少个供电站 |
| stations | 各城市供电站(新建、已有)之和 |
| llHas | 能给当前城市供电的供电站,包括处理之前城市而建立的供电站 |
| left | 给当前城市供电的最左城市 |
| right | 能给当前城市供电的最右城市 |
注意
r可以大于stations.size()
代码
核心代码
class Solution {
public:long long maxPower(vector<int>& stations, int r, int k) {m_iR = r;m_iK = k;m_stations = stations;long long left = 0, right = std::accumulate(stations.begin(), stations.end(),0LL) + k + 1;//左闭右开while (right - left > 1){const long long mid = left + (right - left) / 2;if (TargetNeed(mid)){left = mid;}else{right = mid;}}return left;}//所有城市供电站达到iTarget,需要新建多少供电站bool TargetNeed(long long llTarget){vector<int> stations = m_stations;long long llHas = 0;int left = 0;int right = min(m_iR, (int)stations.size() - 1);//[left,right]表示能够给此城市供电的电站for (int i = 0; i <= right; i++){llHas += stations[i];}long long llNeed = 0; auto Add = [&](){const long long curNeed = llTarget - llHas;if (curNeed > 0){llNeed += curNeed;if (llNeed > m_iK){return false;}stations[right] += curNeed;llHas += curNeed;}return true;};if (!Add()){return false;}for (int i = 1; i < stations.size(); i++){if (i - left > m_iR){ llHas -= stations[left];left++;}if (right+1 < stations.size()){right++;llHas += stations[right];}if (!Add()){return false;}}return true;}int m_iR;int m_iK;vector<int> m_stations;
};
测试用例
template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}
template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}
int main()
{
Solution slu;
vector stations = { 1, 2, 4, 5, 0 };
int r = 0;
int k = 0;
long long res;
stations = { 1, 2, 4, 5, 0 };
r = 1, k = 2;
res = slu.maxPower(stations, r, k);
Assert(5LL, res);
stations = {1 };
r = 0, k = 3;
res = slu.maxPower(stations, r, k);
Assert(4LL, res);
stations = { 0 };
r = 0, k = 0;
res = slu.maxPower(stations, r, k);
Assert(0LL, res);
stations = { 4, 4, 4, 4 };
r = 0, k = 3;
res = slu.maxPower(stations, r, k);
Assert(4LL, res);
stations.assign(2, 1);
r = 1;
k = 1;
res = slu.maxPower(stations, r, k);
Assert(3LL, res);
stations.assign(100000, 100000);
r = 100000;
k = 1e9;
res = slu.maxPower(stations, r, k);
Assert(long long(1e10+1e9+0.5), res);
//CConsole::Out(res);
}
3月旧代码
class Solution {
public:
long long maxPower(vector& stations, int r, int k) {
m_c = stations.size();
CalPower(stations, r);
long long left = *std::min_element(m_vPower.begin(),m_vPower.end());
long long right = left + k+1 ;
while (left + 1 < right)
{
long long iMid = (left + right) / 2;
if (Can(iMid,r,k))
{
left = iMid;
}
else
{
right = iMid;
}
}
return left;
}
void CalPower(vector stations,int r )
{
long long llCur = 0;
for (int i = 0; i < r; i++)
{
llCur += stations[i];
}
for (int i = 0; i < stations.size(); i++)
{
if (i + r < m_c)
{
llCur += stations[i + r];
}
if (i - r - 1 >= 0)
{
llCur -= stations[i - r - 1];
}
m_vPower.push_back(llCur);
}
}
bool Can( long long llMinPower, int r, int k)const
{
long long llAdd = 0;
vector vDiff(m_vPower.size());
for (int i = 0; i < m_vPower.size(); i++)
{
llAdd += vDiff[i];
const long long llNeedAdd = llMinPower - (m_vPower[i] + llAdd);
if (llNeedAdd <= 0 )
{
continue;
}
if (llNeedAdd > k )
{
return false;
}
const int iNewIndex = i + r + r + 1;
if (iNewIndex < m_c)
{
vDiff[iNewIndex] -= llNeedAdd;
}
llAdd += llNeedAdd;
k -= llNeedAdd;
}
return true;
}
vector m_vPower;
int m_c;
};
8月旧代码
class Solution {
public:
long long maxPower(vector& stations, int r, int k) {
m_c = stations.size();
CalPower(stations, r);
long long left = *std::min_element(m_vPower.begin(),m_vPower.end());
long long right = left + k+1 ;
while (left + 1 < right)
{
long long iMid = (left + right) / 2;
if (Can(iMid,r,k))
{
left = iMid;
}
else
{
right = iMid;
}
}
return left;
}
void CalPower(vector stations,int r )
{
long long llCur = 0;
for (int i = 0; i < r; i++)
{
llCur += stations[i];
}
for (int i = 0; i < stations.size(); i++)
{
if (i + r < m_c)
{
llCur += stations[i + r];
}
if (i - r - 1 >= 0)
{
llCur -= stations[i - r - 1];
}
m_vPower.push_back(llCur);
}
}
bool Can( long long llMinPower, int r, int k)const
{
long long llAdd = 0;
vector vDiff(m_vPower.size());
for (int i = 0; i < m_vPower.size(); i++)
{
llAdd += vDiff[i];
const long long llNeedAdd = llMinPower - (m_vPower[i] + llAdd);
if (llNeedAdd <= 0 )
{
continue;
}
if (llNeedAdd > k )
{
return false;
}
const int iNewIndex = i + r + r + 1;
if (iNewIndex < m_c)
{
vDiff[iNewIndex] -= llNeedAdd;
}
llAdd += llNeedAdd;
k -= llNeedAdd;
}
return true;
}
vector m_vPower;
int m_c;
};
扩展阅读
视频课程
有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快
速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
相关下载
想高屋建瓴的学习算法,请下载《闻缺陷则喜算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653
| 充满正能量得对大家说 |
|---|
| 闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
| 墨家名称的来源:有所得以墨记之。 |
| 算法终将统治宇宙,而我们统治算法。《喜缺全书》 |
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开
发环境: VS2022 C++17

相关文章:
C++前缀和算法的应用:最大化城市的最小供电站数目
本文涉及的基础知识点 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 二分法 题目 给你一个下标从 0 开始长度为 n 的整数数组 stations ,其中 stations[i] 表示第 i 座城市的供电站数目。 每个供电站可以在一定 范围 内给所…...
Centos/Linux安装Apahce出现bug汇总
源码安装Apache软件 使用软件:Apahce2.4.58,apr1.5.2, apr-util1.5.4 1.下载apr、apr-util和Apache软件; 2.安装apr压缩包,步骤如下: 第一、解压缩 tar zxvf apr-1.5.2.tar.gz第二、安装 cd /usr/local/sr…...
Scrapy爬虫异步框架(一篇文章齐全)
1、Scrapy框架初识 2、Scrapy框架持久化存储(点击前往查阅) 3、Scrapy框架内置管道(点击前往查阅) 4、Scrapy框架中间件(点击前往查阅) Scrapy 是一个开源的、基于Python的爬虫框架,它提供了…...
基于Hadoop架构的多重分布式BP神经网络的短期负荷预测方法
点我完整下载:基于Hadoop架构的多重分布式BP神经网络的短期负荷预测方法.docx 基于Hadoop架构的多重分布式BP神经网络的短期负荷预测方法 "A Short-term Load Forecasting Method based on Multi-distributed BP Neural Network Architecture with Hadoop Fram…...
Oracle查询数据库中当前用户每个表的数据条数
Oracle查询数据库中当前用户每个表的数据条数 select t.table_name,t.num_rows from user_tables t一般情况下这条语句就可查出想要结果 如果不行 请执行以下脚本 create or replace function count_rows(table_name in varchar2,owner in varchar2 default null)return…...
Windows从源码构建tensorflow(离线编译)
由一开始的在线编译,到后面的离线编译,一路踩坑无数,历经整整6个半小时,终于编译成功!在此记录一下参考过的文章,有时间整理一下踩坑记录。 一、环境配置 在tensorflow官网上有版本对应关系 win10 bazel …...
JMeter处理接口签名sign
写接口脚本的时候,很多接口涉及到签名,今天介绍下用JMeter编写签名脚本的方法。 举个例子,开启红包接口,请求方式为post POST /v1/api/red/open json请求参数 { "red_id":1, "timestamp":"1667033841…...
Android : Java中创建线程的几种方式_简单应用
主方法 MainTest.java package com.example.mythread;import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask;public class MainTest {public static void main(String[] data){ // 以下的方…...
C# Onnx 特征匹配 DeDoDe 检测,不描述---描述,不检测
目录 介绍 效果 模型信息 项目 代码 下载 介绍 github地址:https://github.com/Parskatt/DeDoDe DeDoDe 🎶 Detect, Dont Describe - Describe, Dont Detect, for Local Feature Matching The DeDoDe detector learns to detect 3D consisten…...
第十六章 处理空字符串和 Null 值
文章目录 第十六章 处理空字符串和 Null 值空字符串和 Null 值的默认映射导出值控制空元素的形式 第十六章 处理空字符串和 Null 值 类和属性参数 XMLUSEEMPTYELEMENT XMLIGNORENULL XMLNILNOOBJECT XMLNIL 空字符串和 Null 值的默认映射 下表总结了空字符串和 null 值的…...
MYSQL 处理重复数据
文章目录 前言防止表中出现重复数据统计重复数据过滤重复数据删除重复数据在这里插入代码片后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:Mysql 🐱👓博主在前端领域还有很多知识和技术需要掌握,正…...
世岩清上:未来科技展览的策展视野
面对科技未来,策展视野的核心在于把握趋势,理解人性,并充分运用科技手段提升观众的体验。以下是我对未来科技展览的策展视野。 一、以人为本的设计理念 科技发展的最终目的是服务于人类,提升人们的生活质量。因此,展…...
如何理解2023vivo开发者大会,使用Rust语言编写蓝河操作系统(BlueOS)?
在2023年vivo开发者大会上,vivo宣布使用Rust语言编写其蓝河操作系统(BlueOS)。 什么是Rust语言? Rust 是一种开放源代码系统编程语言,可用于开发高效、安全的软件。 使用 Rust 可管理内存并控制其低级详细信息。 但你…...
Android flutter this and base files have different roots
类似经历者 Android build fails with certain plugins if project is in a different drive (from sdk) 错误描述 我是windows系统,下载 flutter sdk 我是放在D盘,flutter项目是放在E盘,flutter 执行 pub get的时候,会在我C盘…...
Excel动态选择某一行/列的最后一个数据
选择列的最后一个数据: 以A列为例,使用: LOOKUP(1,0/(A:A<>""),A:A)选择行的最后一个数据: 以第3行为例,使用: LOOKUP(1,0/(3:3<>""),3:3)示例程序 列最后一个数据&a…...
扫描条形码到电脑:Barcode to pc 4.6.3 Crack
像专业人士一样使用条形码将条形码发送到 PC 排名第一的智能手机扫描应用程序 将条形码即时发送到计算机程序并自动执行任务的最简单方法 受到全球 500,000 多名用户的信赖 条形码到 PC:Wi-Fi 扫描仪应用程序,条码到 PC:适用于 Android 和 i…...
从0到0.01入门 Webpack| 003.精选 Webpack面试题
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…...
[数据结构]-红黑树
前言 作者:小蜗牛向前冲 名言:我可以接受失败,但我不能接受放弃 如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、红黑树的…...
Android 13.0 Launcher3 app列表页桌面图标按安装时间排序
1.概述 在13.0的系统rom定制化开发中,在对Launcher3进行功能开发时,系统默认的app列表页排序是安装app名称进行排序的, 由于功能的需要要求按照app安装时间进行排序,这就需要找到相关的排序地方,进行排序方式的修改就能完成这个功能 2.Launcher3 app列表页桌面图标按安装…...
QFont如何设置斜体|QlineEdit设置只能输入数字|QThread::finished信号发出后worker未调用析构函数
QFont如何设置斜体 要设置 QFont 的斜体,你可以使用 setItalic() 方法。以下是一个示例代码: #include <QApplication> #include <QLabel> #include <QFont> int main(int argc, char *argv...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
