【C++贪心 二分查找】P8775 [蓝桥杯 2022 省 A] 青蛙过河|普及+
本文涉及知识点
C++贪心
C++二分查找
[蓝桥杯 2022 省 A] 青蛙过河
题目描述
小青蛙住在一条河边,它想到河对岸的学校去学习。小青蛙打算经过河里的石头跳到对岸。
河里的石头排成了一条直线,小青蛙每次跳跃必须落在一块石头或者岸上。不过,每块石头有一个高度,每次小青蛙从一块石头起跳,这块石头的高度就会下降 111,当石头的高度下降到 000 时小青蛙不能再跳到这块石头上(某次跳跃后使石头高度下降到 000 是允许的)。
小青蛙一共需要去学校上 xxx 天课,所以它需要往返 2x2x2x 次。当小青蛙具有一个跳跃能力 yyy 时,它能跳不超过 yyy 的距离。
请问小青蛙的跳跃能力至少是多少才能用这些石头上完 xxx 次课。
输入格式
输入的第一行包含两个整数 n,xn, xn,x, 分别表示河的宽度和小青蛙需要去学校的天数。请注意 2x2x2x 才是实际过河的次数。
第二行包含 n−1n-1n−1 个非负整数 H1,H2,⋯,Hn−1H_{1}, H_{2}, \cdots, H_{n-1}H1,H2,⋯,Hn−1, 其中 Hi>0H_{i}>0Hi>0 表示在河中与 小青蛙的家相距 iii 的地方有一块高度为 HiH_{i}Hi 的石头,Hi=0H_{i}=0Hi=0 表示这个位置没有石头。
输出格式
输出一行, 包含一个整数, 表示小青蛙需要的最低跳跃能力。
样例 #1
样例输入 #1
5 1
1 0 1 0
样例输出 #1
4
提示
【样例解释】
由于只有两块高度为 111 的石头,所以往返只能各用一块。第 111 块石头和对岸的距离为 444,如果小青蛙的跳跃能力为 333 则无法满足要求。所以小青蛙最少需要 444 的跳跃能力。
【评测用例规模与约定】
对于 30%30 \%30% 的评测用例,n≤100n \leq 100n≤100;
对于 60%60 \%60% 的评测用例,n≤1000n \leq 1000n≤1000;
对于所有评测用例,1≤n≤105,1≤x≤109,0≤Hi≤1041 \leq n \leq 10^{5}, 1 \leq x \leq 10^{9}, 0 \leq H_{i} \leq 10^{4}1≤n≤105,1≤x≤109,0≤Hi≤104 。
蓝桥杯 2022 省赛 A 组 F 题。
贪心+二分查找
二分查找:寻找首端
参数范围:[1,n]
Check(mid):
跳跃能力是y,能否跳跃2x次。
heights 记录各石头的高度,前后各增加一个高度为2x的石头,代表起点和终点。
c[i]记录石头i,能够跳出的次数。c[0]=2x
队列记录c[i-y…i-1]及i。
for i = 1 To N
c[i-1]入队
i- 如果队首元素下标 > y,出队。
当 i1 = min(队首元素的跳出次数,height[i])
队首元素的跳出次数 -= i1 如果为0,出队。
height[i]-=i1
c[i] +=i1
返回值:c.back()==2x
第i块石头的前置位置优先用编号(下标)小的。
时间复杂度:O(nlogn)
代码
核心代码
#include <iostream>
#include <sstream>
#include <vector>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<string>
#include<algorithm>
#include<functional>
#include<queue>
#include <stack>
#include<iomanip>
#include<numeric>
#include <math.h>
#include <climits>
#include<assert.h>
#include<cstring>#include <bitset>
using namespace std;template<class T = int>
vector<T> Read(int n,const char* pFormat = "%d") {vector<T> ret(n);for(int i=0;i<n;i++) {scanf(pFormat, &ret[i]); }return ret;
}template<class T = int>
vector<T> Read( const char* pFormat = "%d") {int n;scanf("%d", &n);vector<T> ret;T d;while (n--) {scanf(pFormat, &d);ret.emplace_back(d);}return ret;
}string ReadChar(int n) {string str;char ch;while (n--) {do{scanf("%c", &ch);} while (('\n' == ch));str += ch;}return str;
}template<class INDEX_TYPE>
class CBinarySearch
{
public:CBinarySearch(INDEX_TYPE iMinIndex, INDEX_TYPE iMaxIndex) :m_iMin(iMinIndex), m_iMax(iMaxIndex) {}template<class _Pr>INDEX_TYPE FindFrist(_Pr pr){auto left = m_iMin - 1;auto rightInclue = m_iMax;while (rightInclue - left > 1){const auto mid = left + (rightInclue - left) / 2;if (pr(mid)){rightInclue = mid;}else{left = mid;}}return rightInclue;}template<class _Pr>INDEX_TYPE FindEnd(_Pr pr){INDEX_TYPE leftInclude = m_iMin;INDEX_TYPE right = m_iMax + 1;while (right - leftInclude > 1){const auto mid = leftInclude + (right - leftInclude) / 2;if (pr(mid)){leftInclude = mid;}else{right = mid;}}return leftInclude;}
protected:const INDEX_TYPE m_iMin, m_iMax;
};class Solution {
public:int Ans(int x, vector<int>& heights){heights.insert(heights.begin(), 2 * x);heights.emplace_back(2 * x);const int N = heights.size();auto Check = [&](int mid){auto tmp = heights;vector<int> c(N);c[0] = 2 * x;queue<pair<int, int>> que;for (int i = 1; i < N; i++) {if (c[i - 1] > 0) { que.emplace(c[i - 1], i - 1); }while (que.size() && (que.front().second < i - mid)) {que.pop();}int i1 = 0;while (que.size() && (i1 = min(tmp[i], que.front().first))) {que.front().first -= i1;if (0 == que.front().first) { que.pop(); }tmp[i] -= i1;c[i] += i1;}}return c.back() >= 2 * x;};return CBinarySearch(1, N).FindFrist(Check);}
};int main() {
#ifdef _DEBUGfreopen("a.in", "r", stdin);
#endif // DEBUGint n,x;scanf("%d%d", &n,&x);auto h = Read<int>(n - 1);auto res = Solution().Ans(x, h);cout << res << std::endl;
#ifdef _DEBUG#endif return 0;
}
单元测试
int x;vector<int> h;TEST_METHOD(TestMethod11){x=1,h = { 1,0,1,0 };auto res = Solution().Ans(x,h);AssertEx(4, res);}
扩展阅读
我想对大家说的话 |
---|
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。 |
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作 |
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注 |
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 |
如果程序是一条龙,那算法就是他的是睛 |
失败+反思=成功 成功+反思=成功 |
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。