蓝桥杯C++ AB组辅导课 第二讲 二分与前缀和 Acwing
例题
AcWing 789. 数的范围
给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。
对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。
如果数组中不存在该元素,则返回 -1 -1。
输入格式
第一行包含整数 n 和 q,表示数组长度和询问个数。
第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。
接下来 q 行,每行包含一个整数 k,表示一个询问元素。
输出格式
共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。
如果数组中不存在该元素,则返回 -1 -1。
数据范围
1≤n≤100000
1≤q≤10000
1≤k≤10000
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1
#include <iostream>
using namespace std;const int N = 1e5 + 10;int a[N];int main()
{int n, q; cin >> n >> q;for (int i = 1; i <= n && cin >> a[i]; i ++ );while (q -- ){int k; cin >> k;int l = 0, r = n + 1;while (l + 1 != r){int m = l + r >> 1;if (a[m] < k) l = m;else r = m;}if (a[r] != k){cout << -1 << ' ' << -1 << endl;continue;}cout << r - 1 << ' ';l = 0, r = n + 1;while (l + 1 != r){int m = l + r >> 1;if (a[m] <= k) l = m;else r = m;}cout << l - 1 << endl;}
}
AcWing 790. 数的三次方根
给定一个浮点数 n,求它的三次方根。
输入格式
共一行,包含一个浮点数 n。
输出格式
共一行,包含一个浮点数,表示问题的解。
注意,结果保留 6 位小数。
数据范围
−10000≤n≤10000
输入样例:
1000.00
输出样例:
10.000000
#include <iostream>
#include <iomanip>
using namespace std;const double esp = 1e-8;int main()
{double n; cin >> n;double l = -1e4 - 10, r = 1e4 + 10;while (r - l > esp){double m = (l + r) / 2;if (m * m * m >= n) r = m;else l = m;}cout << fixed << setprecision(6) << r;
}
AcWing 795. 前缀和
输入一个长度为 n 的整数序列。
接下来再输入 m 个询问,每个询问输入一对 l,r。
对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。
输入格式
第一行包含两个整数 n 和 m。
第二行包含 n 个整数,表示整数数列。
接下来 m 行,每行包含两个整数 l 和 r,表示一个询问的区间范围。
输出格式
共 m 行,每行输出一个询问的结果。
数据范围
1≤l≤r≤n,
1≤n,m≤100000,
−1000≤数列中元素的值≤1000
输入样例:
5 3
2 1 3 6 4
1 2
1 3
2 4
输出样例:
3
6
10
#include <iostream>
using namespace std;const int N = 1e5 + 10;int n, m;
int a[N];int main()
{cin >> n >> m;for (int i = 1; i <= n && cin >> a[i]; i ++ ) a[i] += a[i - 1];while (m -- ){int l, r; cin >> l >> r;cout << a[r] - a[l - 1] << endl;}
}
AcWing 796. 子矩阵的和
输入一个 n 行 m 列的整数矩阵,再输入 q 个询问,每个询问包含四个整数 x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。
对于每个询问输出子矩阵中所有数的和。
输入格式
第一行包含三个整数 n,m,q。
接下来 n 行,每行包含 m 个整数,表示整数矩阵。
接下来 q 行,每行包含四个整数 x1,y1,x2,y2,表示一组询问。
输出格式
共 q 行,每行输出一个询问的结果。
数据范围
1≤n,m≤1000,
1≤q≤200000,
1≤x1≤x2≤n,
1≤y1≤y2≤m,
−1000≤矩阵内元素的值≤1000
输入样例:
3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4
输出样例:
17
27
21
#include <iostream>
using namespace std;const int N = 1010;int n, m, q;
int a[N][N];int main()
{cin >> n >> m >> q;for (int i = 1; i <= n; i ++ )for (int j = 1; j <= m; j ++ ){cin >> a[i][j];a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + a[i][j];}while (q -- ){int x1, y1, x2, y2;cin >> x1 >> y1 >> x2 >> y2;cout << a[x2][y2] - a[x1 - 1][y2] - a[x2][y1 - 1] + a[x1 - 1][y1 - 1] << endl;}
}
习题
AcWing 730. 机器人跳跃问题
机器人正在玩一个古老的基于 DOS 的游戏。
游戏中有 N+1 座建筑——从 0 到 N 编号,从左到右排列。
编号为 0 的建筑高度为 0 个单位,编号为 i 的建筑高度为 H(i) 个单位。
起初,机器人在编号为 0 的建筑处。
每一步,它跳到下一个(右边)建筑。
假设机器人在第 k 个建筑,且它现在的能量值是 E,下一步它将跳到第 k+1 个建筑。
如果 H(k+1)>E,那么机器人就失去 H(k+1)−E 的能量值,否则它将得到 E−H(k+1) 的能量值。
游戏目标是到达第 N 个建筑,在这个过程中能量值不能为负数个单位。
现在的问题是机器人至少以多少能量值开始游戏,才可以保证成功完成游戏?
输入格式
第一行输入整数 N。
第二行是 N 个空格分隔的整数,H(1),H(2),…,H(N) 代表建筑物的高度。
输出格式
输出一个整数,表示所需的最少单位的初始能量值上取整后的结果。
数据范围
1≤N,H(i)≤105,
输入样例1:
5
3 4 3 2 4
输出样例1:
4
题意 :
- 初始时
e = h[0]
,依次遍历数列,e += e - h[i]
,求最小的h[0](向上取整)使得过程中e永远大于等于0
思路 :
- 易知,h[0]越大,整个过程中所有的e越大,因此,具有单调性
- 剪枝 :因为h[i]的范围是[1,1e5][1,1e5][1,1e5],因此根据公式,只要在某一状态下e达到1e5,之后一定递增或不变,直接返回true
#include <iostream>
using namespace std;const int N = 1e5 + 10;int n, a[N];bool check(int e)
{for (int i = 1; i <= n; i ++ ){e = 2 * e - a[i];if (e < 0) return false;if (e >= 1e5) return true;}return true;
}int main()
{cin >> n;for (int i = 1; i <= n && cin >> a[i]; i ++ );int l = 0, r = 100010;while (l + 1 != r){int m = l + r >> 1;if (check(m)) r = m;else l = m;}cout << r;
}
AcWing 1221. 四平方和
四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多 4 个正整数的平方和。
如果把 0 包括进去,就正好可以表示为 4 个数的平方和。
比如:
5=02+02+12+22
7=12+12+12+22
对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对 4 个数排序:
0≤a≤b≤c≤d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法。
输入格式
输入一个正整数 N。
输出格式
输出4个非负整数,按从小到大排序,中间用空格分开。
数据范围
0<N<5∗106
输入样例:
5
输出样例:
0 0 1 2
思路 :
- 暴力O(n4)O(n^4)O(n4) 优化为 暴力O(n3)O(n^3)O(n3),仍然超时
- 哈希表法 虽然复杂度为O(n2)O(n^2)O(n2),但常数太大,仍然超时
- 采用二分法,虽然复杂度为O(n2logn)O(n^2logn)O(n2logn),可以通过
- 二分枚举的时候仍然需要优化;有两个枚举优化之处:1.双重循环时,易知第二重循环
c * c + d * d <= n
;2.第二个优化不容易发现,而且是题目的先决条件,0≤a≤b≤c≤d0≤a≤b≤c≤d0≤a≤b≤c≤d,因此第二重循环以第一重循环为起始
#include <iostream>
#include <algorithm>
using namespace std;const int N = 9e6;struct Sum
{int s, c, d;bool operator< (const Sum &w) const{if (s != w.s) return s < w.s;if (c != w.c) return c < w.c;return d < w.d;}
}sum[N];
int n, m;int main()
{cin >> n;for (int c = 0; c * c <= n; c ++ )for (int d = c; c * c + d * d <= n; d ++ )sum[ ++ m] = {c * c + d * d, c, d};sort(sum + 1, sum + 1 + m);for (int a = 0; a * a <= n; a ++ )for (int b = a; a * a + b * b <= n; b ++ ){int need = n - a * a - b * b;int l = 0, r = m + 1;while (l + 1 != r){int mid = l + r >> 1;if (sum[mid].s >= need) r = mid;else l = mid;}if (sum[r].s == need){cout << a << ' ' << b << ' ' << sum[r].c << ' ' << sum[r].d;return 0;}}
}
AcWing 1227. 分巧克力
儿童节那天有 K 位小朋友到小明家做客。
小明拿出了珍藏的巧克力招待小朋友们。
小明一共有 N 块巧克力,其中第 i 块是 Hi×Wi 的方格组成的长方形。
为了公平起见,小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。
切出的巧克力需要满足:
形状是正方形,边长是整数
大小相同
例如一块 6×5 的巧克力可以切出 6 块 2×2 的巧克力或者 2 块 3×3 的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?
输入格式
第一行包含两个整数 N 和 K。
以下 N 行每行包含两个整数 Hi 和 Wi。
输入保证每位小朋友至少能获得一块 1×1 的巧克力。
输出格式
输出切出的正方形巧克力最大可能的边长。
数据范围
1≤N,K≤105,
1≤Hi,Wi≤105
输入样例:
2 10
6 5
5 6
输出样例:
2
#include <iostream>
using namespace std;const int N = 1e5 + 10;int n, k;
int h[N], w[N];bool check(int len)
{int res = 0;for (int i = 1; i <= n; i ++ ){res += (h[i] / len) * (w[i] / len);if (res >= k) return true;}return false;
}int main()
{cin >> n >> k;for (int i = 1; i <= n && cin >> h[i] >> w[i]; i ++ );int l = 0, r = 1e5 + 1;while (l + 1 != r){int mid = l + r >> 1;if (check(mid)) l = mid;else r = mid;}cout << l;
}
AcWing 99. 激光炸弹
地图上有 N 个目标,用整数 Xi,Yi 表示目标在地图上的位置,每个目标都有一个价值 Wi。
注意:不同目标可能在同一位置。
现在有一种新型的激光炸弹,可以摧毁一个包含 R×R 个位置的正方形内的所有目标。
激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆炸范围,即那个正方形的边必须和 x,y 轴平行。
求一颗炸弹最多能炸掉地图上总价值为多少的目标。
输入格式
第一行输入正整数 N 和 R,分别代表地图上的目标数目和正方形的边长,数据用空格隔开。
接下来 N 行,每行输入一组数据,每组数据包括三个整数 Xi,Yi,Wi,分别代表目标的 x 坐标,y 坐标和价值,数据用空格隔开。
输出格式
输出一个正整数,代表一颗炸弹最多能炸掉地图上目标的总价值数目。
数据范围
0≤R≤109
0<N≤10000,
0≤Xi,Yi≤5000
0≤Wi≤1000
输入样例:
2 1
0 0 1
1 1 1
输出样例:
1
思路 :
- 由输入的数据我们可以得到这个地图的宽高;注意这个地图的宽高至少是R,否则就无法进入循环了
- R最多是5001,多出来的部分没有意义
- 枚举框起来的范围时,注意我们枚举右下角
#include <iostream>
using namespace std;const int N = 5010;int cnt, R;
int w[N][N];int main()
{cin >> cnt >> R;R = min(R, 5001);int n = R, m = R;while (cnt -- ){int x, y, ww;cin >> x >> y >> ww;x ++ , y ++ ;n = max(n, x), m = max(m, y);w[x][y] += ww;}for (int i = 1; i <= n; i ++ )for (int j = 1; j <= m; j ++ )w[i][j] = w[i - 1][j] + w[i][j - 1] - w[i - 1][j - 1] + w[i][j];int res = 0;for (int x2 = R; x2 <= n; x2 ++ )for (int y2 = R; y2 <= m; y2 ++ ){int x1 = x2 - R + 1, y1 = y2 - R + 1;res = max(res, w[x2][y2] - w[x1 - 1][y2] - w[x2][y1 - 1] + w[x1 - 1][y1 - 1]);}cout << res << endl;
}
AcWing 1230. K倍区间
给定一个长度为 N 的数列,A1,A2,…AN,如果其中一段连续的子序列 Ai,Ai+1,…Aj 之和是 K 的倍数,我们就称这个区间 [i,j] 是 K 倍区间。
你能求出数列中总共有多少个 K 倍区间吗?
输入格式
第一行包含两个整数 N 和 K。
以下 N 行每行包含一个整数 Ai。
输出格式
输出一个整数,代表 K 倍区间的数目。
数据范围
1≤N,K≤100000,
1≤Ai≤100000
输入样例:
5 2
1
2
3
4
5
输出样例:
6
题意 :
- 这里i可以等于j
思路 :
- (sum[r]−sum[l−1])(sum[r] - sum[l - 1])(sum[r]−sum[l−1]) % k == 0,推出sum[r] % k == sum[l - 1] % k
- 因此,一维循环即可。遍历到第i个元素时,只要答案累加 前面 与它 模的结果相同 的个数即可,同时 维护 模的结果 的序列
- 注意这道题开long long,因为区间数溢出int了
#include <iostream>
using namespace std;typedef long long ll;const int N = 1e5 + 10;ll n, k;
ll a[N], cnt[N];int main()
{cin >> n >> k;for (int i = 1; i <= n && cin >> a[i]; i ++ ) a[i] += a[i - 1];ll res = 0;for (int i = 1; i <= n; i ++ ){res += cnt[a[i] % k];if (a[i] % k == 0) res ++ ;cnt[a[i] % k] ++ ;}cout << res;
}
蓝桥杯C++ AB组辅导课 第二讲 二分与前缀和 Acwing相关推荐
- 蓝桥杯C++ AB组辅导课 第一讲 递归与递推 Acwing
例题 AcWing 92. 递归实现指数型枚举 从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案. 输入格式 输入一个整数 n. 输出格式 每行输出一种方案. 同一行内的数必须升序 ...
- 蓝桥杯C++ AB组辅导课
整理的算法模板合集: ACM模板 今天在AcWing闲逛白嫖到了yxc老师的蓝桥杯C++ AB组辅导课的题单,正好快要蓝桥杯了,我准备每天花半个小时刷5道这个题单里的水题,练一练,不然到时候我各种花里 ...
- 【AcWing】蓝桥杯C++ AB组辅导课
蓝桥杯 C++ AB 组辅导课 教学计划与递归 如何准备蓝桥杯比赛 做题的套路 第一讲 递归与递推 递归实现指数型枚举 递归实现排列型枚举 递归实现组合型枚举 AcWing116.飞行员兄弟 第二讲 ...
- 蓝桥杯C++ AB组辅导课 第六讲 双指针、BFS与图论 Acwing
例题 AcWing 1238. 日志统计 小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有 N 行. 其中每一行的格式是: ts id 表示在 ts 时刻编号 id ...
- AcWing蓝桥杯AB组辅导课08、数论
文章目录 前言 一.数论 例题 例题1:AcWing 1246. 等差数列(最大公约数,第十届蓝桥杯省赛C++B第7题) 分析 题解:最大公约数 例题2:AcWing 1295. X的因子链(算数基本 ...
- AcWing蓝桥杯AB组辅导课07、贪心
文章目录 前言 一.贪心 模板题 例题1:AcWing 104. 货仓选址(贪心,简单,算法竞赛进阶指南) 分析 题解:贪心思路 例题 例题1:AcWing 1055. 股票买卖 II(贪心.状态机, ...
- AcWing蓝桥杯AB组辅导课10、疑难杂题
文章目录 前言 例题1:AcWing 1242. 修改数组(并查集) 分析 题解:单链表式并查集 例题2:AcWing 1234. 倍数问题(背包问题+贪心) 分析 题解1:01背包问题,三维解法(贪 ...
- 蓝桥杯C/C++ AB组辅导课
文章目录 注意 algorithm 字符串 剪枝 暴力常识 1S时间复杂度 数论 暴力流打法 二进制巧用 归并排序 并查集(查找图中的环) 线段树 大数 国赛准备注意事项 还愿 后记 注意 注意数据范 ...
- AcWing 蓝桥杯AB组辅导课 05、树状数组与线段树
文章目录 前言 一.树状数组 1.1.树状数组知识点 1.2.树状数组代码模板 模板题:AcWing 1264. 动态求连续区间和 例题 例题1.AcWing 1265. 数星星[中等,信息学奥赛一本 ...
最新文章
- 10个角度分析软件工程师应该知道的100件事
- oracle对sga统计信息不对,关于oracle sga设置的总结,很经典--转
- FireDAC 下的 Sqlite [7] - 备份、优化、事务(Transaction)
- 在log4j中使用自定义的Appender
- Javascript 函数详解
- 9.MySQL数据查询SQL
- LeetCode刷题:向数组中追加 K 个整数
- 从零开始学MVC3——创建项目
- 职高学的计算机单招考试能换专业吗,高职单招录取后可以换专业吗
- c++ builder xe2 字符串转日期
- Bilinear Pairing双线性配对的解释
- 谷歌浏览器无法定位程序输入点解决方法
- IPC进程间通信/跨进程通信
- nodejs 异常的处理
- AI人工智能基础自学(一)
- RAP2环境部署(nginx代理模式)及运维
- MATLAB classificationLearner
- 微信公众平台消息管理与群发图文教程
- 2022 年度「博客之星」评选TOP 200进100结果已出炉
- 公司建网站多少钱?【网站多少钱】
热门文章
- 【转】物料与客户主数据的税分类
- SE16N新改表内容方法!!!
- 使用事务代码MB51+Excel中的数据透视表实现 收发存报表
- 为什么你的记忆总会越来越模糊?
- SAP PP 中关于计划订单和生产订单的日期计算
- 简颢集团“风口”下的投资机会 新能源共享领域的机遇与挑战
- 迷宫android游戏代码,C++打造迷宫游戏,直接上代码
- php管理用户名和密码,管理员用户名/密码不适用于PHP
- mysql数据库怎么安装建表_mysql数据库安装及建表注意事项
- 自己的模块给其他人调用是怎么打包的_webpack实战——模块打包