例题

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相关推荐

  1. 蓝桥杯C++ AB组辅导课 第一讲 递归与递推 Acwing

    例题 AcWing 92. 递归实现指数型枚举 从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案. 输入格式 输入一个整数 n. 输出格式 每行输出一种方案. 同一行内的数必须升序 ...

  2. 蓝桥杯C++ AB组辅导课

    整理的算法模板合集: ACM模板 今天在AcWing闲逛白嫖到了yxc老师的蓝桥杯C++ AB组辅导课的题单,正好快要蓝桥杯了,我准备每天花半个小时刷5道这个题单里的水题,练一练,不然到时候我各种花里 ...

  3. 【AcWing】蓝桥杯C++ AB组辅导课

    蓝桥杯 C++ AB 组辅导课 教学计划与递归 如何准备蓝桥杯比赛 做题的套路 第一讲 递归与递推 递归实现指数型枚举 递归实现排列型枚举 递归实现组合型枚举 AcWing116.飞行员兄弟 第二讲 ...

  4. 蓝桥杯C++ AB组辅导课 第六讲 双指针、BFS与图论 Acwing

    例题 AcWing 1238. 日志统计 小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有 N 行. 其中每一行的格式是: ts id 表示在 ts 时刻编号 id ...

  5. AcWing蓝桥杯AB组辅导课08、数论

    文章目录 前言 一.数论 例题 例题1:AcWing 1246. 等差数列(最大公约数,第十届蓝桥杯省赛C++B第7题) 分析 题解:最大公约数 例题2:AcWing 1295. X的因子链(算数基本 ...

  6. AcWing蓝桥杯AB组辅导课07、贪心

    文章目录 前言 一.贪心 模板题 例题1:AcWing 104. 货仓选址(贪心,简单,算法竞赛进阶指南) 分析 题解:贪心思路 例题 例题1:AcWing 1055. 股票买卖 II(贪心.状态机, ...

  7. AcWing蓝桥杯AB组辅导课10、疑难杂题

    文章目录 前言 例题1:AcWing 1242. 修改数组(并查集) 分析 题解:单链表式并查集 例题2:AcWing 1234. 倍数问题(背包问题+贪心) 分析 题解1:01背包问题,三维解法(贪 ...

  8. 蓝桥杯C/C++ AB组辅导课

    文章目录 注意 algorithm 字符串 剪枝 暴力常识 1S时间复杂度 数论 暴力流打法 二进制巧用 归并排序 并查集(查找图中的环) 线段树 大数 国赛准备注意事项 还愿 后记 注意 注意数据范 ...

  9. AcWing 蓝桥杯AB组辅导课 05、树状数组与线段树

    文章目录 前言 一.树状数组 1.1.树状数组知识点 1.2.树状数组代码模板 模板题:AcWing 1264. 动态求连续区间和 例题 例题1.AcWing 1265. 数星星[中等,信息学奥赛一本 ...

最新文章

  1. 10个角度分析软件工程师应该知道的100件事
  2. oracle对sga统计信息不对,关于oracle sga设置的总结,很经典--转
  3. FireDAC 下的 Sqlite [7] - 备份、优化、事务(Transaction)
  4. 在log4j中使用自定义的Appender
  5. Javascript 函数详解
  6. 9.MySQL数据查询SQL
  7. LeetCode刷题:向数组中追加 K 个整数
  8. 从零开始学MVC3——创建项目
  9. 职高学的计算机单招考试能换专业吗,高职单招录取后可以换专业吗
  10. c++ builder xe2 字符串转日期
  11. Bilinear Pairing双线性配对的解释
  12. 谷歌浏览器无法定位程序输入点解决方法
  13. IPC进程间通信/跨进程通信
  14. nodejs 异常的处理
  15. AI人工智能基础自学(一)
  16. RAP2环境部署(nginx代理模式)及运维
  17. MATLAB classificationLearner
  18. 微信公众平台消息管理与群发图文教程
  19. 2022 年度「博客之星」评选TOP 200进100结果已出炉
  20. 公司建网站多少钱?【网站多少钱】

热门文章

  1. 【转】物料与客户主数据的税分类
  2. SE16N新改表内容方法!!!
  3. 使用事务代码MB51+Excel中的数据透视表实现 收发存报表
  4. 为什么你的记忆总会越来越模糊?
  5. SAP PP 中关于计划订单和生产订单的日期计算
  6. 简颢集团“风口”下的投资机会 新能源共享领域的机遇与挑战
  7. 迷宫android游戏代码,C++打造迷宫游戏,直接上代码
  8. php管理用户名和密码,管理员用户名/密码不适用于PHP
  9. mysql数据库怎么安装建表_mysql数据库安装及建表注意事项
  10. 自己的模块给其他人调用是怎么打包的_webpack实战——模块打包