贪心算法的核心特征是?
考点:贪心的定义。
解析:贪心 = 每步做局部最优选择、一条路走到底不回溯,希望局部最优积累成全局最优。
排除法:枚举全部方案是暴力搜索;分解合并是分治;缓存中间结果是动态规划/记忆化,均非贪心的特征。
对一个数组做二分查找,必须满足的前提是?
考点:二分查找的适用条件。
解析:二分靠与中点比较后排除一侧,这依赖单调性——数组有序才能确定答案在哪一侧。
排除法:长度不必是 2 的幂;元素可重复(求最左/最右位置);链表不能随机访问,无法二分。
一个递归函数要能正确终止,必须具备?
考点:递归的三要素。
解析:没有终止条件、或参数不向终止方向变化,递归会无限展开直至栈溢出。
排除法:调用一次(如单支递归)也合法;全局变量非必需;void 型递归不返回值。
用数组递推斐波那契 f[i]=f[i-1]+f[i-2],正确的填表顺序是?
考点:递推的依赖方向。
解析:算 f[i] 时依赖的 f[i-1]、f[i-2] 必须已算好,所以自底向上从边界依次填。
排除法:倒着填时 f[i-1] 尚未算出;递推有严格依赖序,不能任意。
在 1000 个有序元素中做二分查找,最坏情况大约比较多少次?
考点:二分查找的比较次数。
解析:每次比较把候选区间减半,次数约 。
排除法:100 次、500 次是线性扫描的量级;30 次是 规模的误估( 才对应 30 次)。
下列哪种情形最容易导致调用栈溢出?
考点:调用栈空间。
解析:每层递归在调用栈占一个栈帧,栈通常只有几 MB,10 万层栈帧会撑爆。
排除法:循环次数不占栈;全局数组在静态区;30 层深度毫无压力。
阅读标准二分(闭区间写法):
01int a[] = {2, 5, 8, 11, 15, 19, 23}; // 下标 0..6 02int l = 0, r = 6, x = 19; 03while (l <= r) { 04 int mid = (l + r) / 2; 05 if (a[mid] == x) { cout << mid; break; } 06 else if (a[mid] < x) l = mid + 1; 07 else r = mid - 1; 08}
考点:标准二分模板的执行追踪。
解析:第一次 mid=(0+6)/2=3,a[3]=11<19,走 l=mid+1 得 [4,6];第二次 mid=5,a[5]=19 命中。
排除法:a[6] 在第三次才可能访问;a[4]、a[3] 与 mid 取值顺序不符。
预处理「跳 1、2、4、8、…、2ᵏ 步」的信息,任意大步长由若干 2 的幂拼出。这种思想是?
考点:倍增的基本思想。
解析:任何非负整数都能写成 2 的幂之和,预处理好 2 的幂步信息后,走任意 k 步只需 O(log k) 次拼接。
排除法:贪心是局部最优选择;分治是划分合并;动态规划是状态转移,均不涉及幂步拼接。
用快速幂计算 ,乘法次数的量级是?
考点:快速幂的复杂度。
解析:指数每次平方减半,把 k 写成二进制只需 轮乘法。
排除法:O(k) 是逐个相乘的朴素做法;O(√k)、O(1) 与二分指数过程不符。
爬楼梯递推 f[i]=f[i-1]+f[i-2] 忘记初始化 f[1]=1, f[2]=2,会导致?
考点:递推的边界。
解析:递推是链式的,边界错则每个依赖它的 f[i] 都错,误差会向后传播。
排除法:这不是语法错误,不会编译失败;误差传播到全部,不是局部或常数差。
蛋糕切成 4 段:6、9、7、12 厘米。分给 6 人,每份为整数厘米、必须来自同一段(段可切开、不可拼接)。每人最多分到几厘米?
考点:二分答案——最大化每人份量。
解析:验证 x 是否可行:。x=4 时 1+2+1+3=7 可行;x=5 时 1+1+1+2=5 不可行,故最大 4。
排除法:3 太小(明显可行但不最大);5、6 均不可行。
3 根原木长 10、24、15 厘米,切出 7 段等长木条(整数厘米,碎料丢弃、不可拼接)。每段最长几厘米?
考点:二分答案——等长段数判定。
解析:验证 。x=6 时 1+4+2=7 可行;x=7 时 1+3+2=6 不可行,故最大 6。
排除法:5 可行但不最大;7、8 段数不足。
5 人接水需 3、6、1、4、2 分钟,只有一个水龙头。每个人的等待时间为排在前面的人接水时间之和(第一人等待 0)。最短的总等待时间是?
考点:贪心——短作业优先。
解析:按 1、2、3、4、6 排,等待分别为 0、1、3、6、10,总 20 分钟。最优性由交换论证保证:相邻两人长的在前时,交换后总等待减少。
排除法:36 是按 3、6、1、4、2 原序;26、22 不是最小。
6 个活动起止时间为 [1,4]、[2,6]、[3,5]、[5,7]、[6,9]、[8,10]。同一时间只能参加一个,端点相接不算冲突。最多能参加几个?
考点:贪心——按结束时间排序的区间调度。
解析:按结束时间排序后贪心扫描:选 [1,4],跳过 [2,6]、[3,5],选 [5,7],跳过 [6,9],选 [8,10],共 3 个。
排除法:选 [1,4]+[5,7]+[8,10] 已是最大;2 个是选了过长区间的结果,4、5 个不存在可行方案。
4 堆果子有 1、2、3、4 个。每次合并任意两堆,体力消耗等于两堆个数之和,直到只剩一堆。最小总体力消耗是?
考点:贪心——每次合并最小的两堆。
解析:1+2=3(耗 3),3+3=6(耗 6),4+6=10(耗 10),总 19。小堆被叠的次数多,应尽早合并。
排除法:26、30 是把较大的堆先合(先 3+4 等)的结果;10 只是最后一次的体力。
「二分答案」能够使用的核心前提是?
考点:二分答案的模型。
解析:二分答案 = 对候选值 x 快速判定是否可行,且可行性随 x 单调(一旦越界就翻转),才能夹出边界。
排除法:整数不是必须(实数也可二分);规模与字样都不是前提。
求「check 为真的最大 x」:
01int l = 0, r = n; 02while (l < r) { 03 int mid = (l + r) / 2; 04 if (check(mid)) l = mid; 05 else r = mid - 1; 06}
考点:整数二分取整方向与死循环。
解析:r=l+1 时 mid=(l+r)/2 向下取整得 l,若 check(l) 为真则 l=mid 使区间不变,死循环。含 l=mid 的分支必须上取整。
排除法:这正是死循环而非正常结束或越界;答案边界虽可推出 l,但程序跑不完。
左闭右开模板找「第一个 ≥ x 的位置」:
01int l = 0, r = n; 02while (l < r) { 03 int mid = (l + r) / 2; 04 if (a[mid] >= x) r = mid; 05 else l = mid + 1; 06}
考点:找左边界模板的执行追踪。
解析:l=0,r=4 → mid=2,a[2]=3≥3,r=2 → mid=1,a[1]=3≥3,r=1 → mid=0,a[0]=1<3,l=1;l=r=1 结束,即第一个 3 的下标。
排除法:2 是最后一个 3 的下标;3 是 upper_bound 的结果;0 是第一个元素。
实数域二分求 :
01double l = 0, r = x; 02for (int _ = 0; _ < 100; _++) { 03 double mid = (l + r) / 2; 04 if (mid * mid <= x) l = mid; 05 else r = mid; 06}
考点:实数二分的终止条件。
解析:每轮区间严格减半,100 轮后宽 x/2¹⁰⁰,远低于 double 精度,视为收敛。
排除法:x/100 是把减半误当均分;double 精度有限,不可能恰好为 0;仍为 x 则根本没收敛。
上 n 阶楼梯,每次可上 1 阶或 2 阶。方案数 f(n) 满足的递推是?
考点:递推的建立——爬楼梯。
解析:最后一步跨 1 阶剩 n-1 阶、跨 2 阶剩 n-2 阶,两类互斥完备,方案相加。
排除法:2·f(n-1) 会重复计数;n!、2ⁿ 与「每次一步或两步」的约束不符。
数字三角形:
2 3 4 6 5 1
考点:递推/动态规划——数字三角形。
解析:自底向上:底行 6、5、1;中间行 3+max(6,5)=9、4+max(5,1)=9;顶 2+9=11,路径 2→4→5。
排除法:10、8、7 都是未取最大子路径或路径选择错误的结果。
杨辉三角按 C(n,k)=C(n-1,k-1)+C(n-1,k) 逐行递推。推到第 5 行(n=5),该行中间三个数依次是?
考点:组合数递推——杨辉三角。
解析:逐行:1,1 → 1,2,1 → 1,3,3,1 → 1,4,6,4,1 → 1,5,10,10,5,1。第 5 行中间三个是 5、10、10。
排除法:9 不是杨辉三角中的数(三角形内相邻两数之和);4、8 是把上一行数据弄混。
汉诺塔递归:
01void hanoi(int n, char from, char to, char via) { 02 if (n == 0) return; 03 hanoi(n - 1, from, via, to); 04 cout << "move " << n << ": " << from << "->" << to << "\n"; 05 hanoi(n - 1, via, to, from); 06}
hanoi(3, 'A', 'C', 'B'),输出的第一行是?
考点:递归代码的执行追踪。
解析:打印语句位于两次递归调用之间,最小的盘子最先完成递归并打印:hanoi(1,A,C,B) 输出 move 1: A->C。
排除法:move 3 是整棵递归树的最后一次输出;move 1: A->B 是把目标柱写错。
约瑟夫环线性递推(从 0 报数,报到 k-1 出列):
01int f = 0; 02for (int m = 2; m <= n; m++) 03 f = ____;
考点:约瑟夫环的递推转移。
解析:m 人圈第一个出列者是 (k-1)%m,剩余 m-1 人构成子问题;由子问题编号反推原编号要平移 k 再对 m 取模。
排除法:(f+k)/m 会丢余数;f%m+k、f+1)%k 都不是「平移后取模」的正确形式。
有序数组 a = {1, 3, 3, 7},表达式 lower_bound(a, a + 4, 3) - a 的值是?
考点:lower_bound 的语义。
解析:lower_bound 返回第一个 ≥ x 的迭代器,两个 3 中靠前的是下标 1。
排除法:2 是最后一个 3;3 是 upper_bound(3) 的结果;0 对应第一个元素。
证明「按结束时间排序的活动选择」最优,常用的证明手法是?
考点:贪心正确性的证明方法。
解析:交换论证:若最优解中相邻活动与贪心顺序不同,交换后解不变差,逐步替换成贪心解,故贪心解也最优。
排除法:反证/归纳是通用框架但不指向「交换相邻两项」这一步;构造法用于存在性证明,非贪心最优性证明。
起点到终点相距 25 米,其间 5 块石头距起点分别为 2、11、14、17、21 米。选手必须从起点跳到终点,只能落在石头或起终点上。最多搬走 2 块石头,要使最短单步距离尽量大,这个最大值是?
考点:二分答案——最小值最大化。
解析:验证「间距 ≥ d 可行」需搬几块:d=4 时保留 0、11、17、21、25(搬掉 2、14 两块),可行;d=5 时 2、14、21 都要搬,需 3 块,不可行。故最大为 4。
排除法:5、6 需搬的石头超过 2 块;3 可行但不最大。
「数轴上选 m 个点,最大化最小间距」的模板:
01bool check(int d) { 02 int cnt = 1, last = x[0]; 03 for (int i = 1; i < n; i++) 04 if (x[i] - last >= d) { cnt++; last = x[i]; } 05 return cnt >= m; 06}
check 函数的时间复杂度是?
考点:二分答案中 check 的复杂度。
解析:check 从左到右线性扫描一遍,每元素常数次,O(n)。整题总复杂度 O(n log V)(V 为坐标极差)。
排除法:n log n 是整题复杂度的一部分或排序;log n 是二分的轮数;n² 与线性扫描不符。
n 封信全部装错(每封都不在自己的信封里)的方案数 D(n) 满足?
考点:错排的递推。
解析:第 n 封信装进第 i 个信封(n-1 种):若信 i 恰好装进信封 n,剩 n-2 个错排;否则等价于 n-1 个错排。D(n)=(n-1)(D(n-1)+D(n-2))。
排除法:n·D(n-1)、D(n-1)+D(n-2) 都非错排的转移;n-1)! 是圆周排列不是错排。
n 个元素依次进栈、任意时刻可出栈,不同的出栈序列共有(递推表示,C(0)=1)?
考点:卡特兰数——栈模型。
解析:按第一个出栈的元素是第 i+1 个入栈者分类,其左侧 i 个与右侧 n-1-i 个相互独立,。
排除法:n! 是排列数(不是所有排列都合法);2ⁿ、n² 与进出栈的合法序列数不符。
0/1 背包容量 10:物品 A(重 7,值 9)、B(重 5,值 5)、C(重 5,值 5)。按性价比贪心选 A 后总价值 9,而选 B+C 总价值 10。这说明了?
考点:贪心失效与 0/1 背包。
解析:物品不可分割时,先拿高性价比的可能浪费容量。0/1 背包的最优子结构需要 DP:。
排除法:按价值、按重量贪心都有类似反例;数据本身合法,是贪心策略不适用。
整数二分中,分支包含 l = mid(mid 留在区间内)时,mid 应取?
考点:整数二分的取整方向。
解析:l=mid 分支存在时必须向上取整,否则 r=l+1 时 mid 落到 l、区间不缩、死循环。口诀:见 l=mid 上取整,见 r=mid 下取整。
排除法:(l+r)/2 下取整正是死循环来源;(l+r-1)/2 更小更危险;取整方向必须配套,不能任取。
斐波那契滚动写法:
01int a = 0, b = 1; // f(0), f(1) 02for (int i = 2; i <= n; i++) { 03 int c = a + b; 04 a = b; b = c; 05}
考点:递推的空间优化与追踪。
解析:循环依次滚出 f(2)=1, f(3)=2, …, f(10)=55,结束时 b=f(10)=55。
排除法:89 是 f(11);34 是 f(9);21 是 f(8),均少滚或多滚了一轮。
倍增求「从 i 跳 k 步到哪」的预处理:
01up[0][i] = next[i]; 02for (int k = 1; (1 << k) <= n; k++) 03 for (int i = 0; i < n; i++) 04 up[k][i] = ____;
考点:倍增的递推式。
解析:跳 2ᵏ 步 = 先跳 2ᵏ⁻¹ 步、再从落点跳 2ᵏ⁻¹ 步,两级拼接:up[k][i] = up[k-1][ up[k-1][i] ]。
排除法:加位移量是把下标当距离;up[k][...] 使用未算好的当前层;next 只跳一步,无法构成大步。
关于二分与倍增的适用条件,下列说法正确的是?
考点:二分 vs 倍增。
解析:二分靠「可行性随候选单调」夹出答案;倍增靠「任意量 = 2 的幂之和」拼步长,不要求单调(快速幂、LCA、第 k 后继都能用)。
排除法:倍增不求最值也可用;复杂度依问题而异;「都要求单调」混淆了两者前提。
递归式 T(n) = 2T(n-1) + 1,T(1)=1(如汉诺塔)展开后 T(n) 的量级是?
考点:递归式的展开。
解析:T(n)=2ⁿ⁻¹·T(1)+(2ⁿ⁻¹−1)=2ⁿ−1,指数级。与「规模减半」的 2T(n/2) 完全不同。
排除法:n log n、n²、n 都是多项式级,与每层翻倍累加不符。
计算 a¹³ 时,13 的二进制为 1101,快速幂把 a¹³ 拆成?
考点:快速幂的二进制拆解。
解析:13 = 8+4+1,对应二进制位 1101,所以 a¹³ = a⁸·a⁴·a¹。
排除法:a⁴·a²·a¹ 是 7 的拆解;逐项相乘违背快速幂;a⁶·a⁷ 不是 2 的幂拼接。
设有 个已排好序的数据元素,采用折半查找时,最大比较次数为( )。
D:7。折半查找最大比较次数 ⌊log₂n⌋+1:100 满足 2⁶=64<100≤128=2⁷,最多比较 6+1=7 次;其余 6/8/10 均与公式不符。
新学期开学了,小胖想减肥,健身教练给小胖制定了两个训练方案。方案一:每次连续跑 公里可以消耗 千卡(耗时半小时);方案二:每次连续跑 公里可以消耗 千卡(耗时 小时)。小胖每周周一到周四能抽出半小时跑步,周五到周日能抽出一小时跑步。另外,教练建议小胖每周最多跑 公里,否则会损伤膝盖。请问如果小胖想严格执行教练的训练方案,并且不想损伤膝盖,每周最多通过跑步消耗多少千卡?( )
B:2400。每公里千卡:3km 方案 100/公里,5km 方案 120/公里,5km 更划算。21 公里上限内:3 次 5km+2 次 3km=21km,消耗 3×600+2×300=2400 千卡。
1 #include <iostream> 2 using namespace std; 3 const int maxn = 10000; 4 int n; 5 int a[maxn]; 6 int b[maxn]; 7 int f(int l, int r, int depth) { 8 if (l > r) 9 return 0; 10 int min = maxn, mink; 11 for (int i = l; i <= r; ++i) { 12 if (min > a[i]) { 13 min = a[i]; 14 mink = i; 15 } 16 } 17 int lres = f(l, mink - 1, depth + 1); 18 int rres = f(mink + 1, r, depth + 1); 19 return lres + rres + depth * b[mink]; 20 } 21 int main() { 22 cin >> n; 23 for (int i = 0; i < n; ++i) 24 cin >> a[i]; 25 for (int i = 0; i < n; ++i) 26 cin >> b[i]; 27 cout << f(0, n - 1, 1) << endl; 28 return 0; 29 }
如果 a 数组有重复的数字,则程序运行时会发生错误。( )
如果 b 数组全为 ,则输出为 。( )
当 时,最坏情况下,与第 行的比较运算执行的次数最接近的是( )。
(1 分)当 时,最好情况下,与第 行的比较运算执行的次数最接近的是( )。
(1 分)当 时,若 b 数组满足对任意 都有 b[i] = i + 1,那么输出最大为( )。
当 时,若 b 数组满足对任意 都有 b[i] = 1,那么输出最小为( )。
(矩阵变幻)有一个奇幻的矩阵,在不停地变幻,其变幻方式为:数字 变成矩阵 ,数字 变成矩阵 。最初该矩阵只有一个元素 ,变幻 次后,矩阵会变成什么样?
例如,矩阵最初为:;矩阵变幻 次后:;矩阵变幻 次后:。
输入一行一个不超过 的正整数 。输出变幻 次后的矩阵。
试补全程序。
提示:
<< 表示二进制左移运算符,例如 << ;
而 ^ 表示二进制异或运算符,它将两个参与运算的数中的每个对应的二进制位一一进行比较,若两个二进制位相同,则运算结果的对应二进制位为 ,反之为 。
1 #include <cstdio> 2 using namespace std; 3 int n; 4 const int max_size = 1 << 10; 5 6 int res[max_size][max_size]; 7 8 void recursive(int x, int y, int n, int t) { 9 if (n == 0) { 10 res[x][y] = ①; 11 return; 12 } 13 int step = 1 << (n - 1); 14 recursive(②, n - 1, t); 15 recursive(x, y + step, n - 1, t); 16 recursive(x + step, y, n - 1, t); 17 recursive(③, n - 1, !t); 18 } 19 20 int main() { 21 scanf("%d", &n); 22 recursive(0, 0, ④); 23 int size = ⑤; 24 for (int i = 0; i < size; ++i) { 25 for (int j = 0; j < size; ++j) 26 printf("%d", res[i][j]); 27 puts(""); 28 } 29 return 0; 30 }
①处应填( )。
(1 分)②处应填( )。
(1 分)③处应填( )。
(1 分)④处应填( )。
(1 分)⑤处应填( )。
(1 分)设 是 个实数的数组,考虑下面的递归算法:
XYZ(A[1..n]) 1 if n = 1 then return A[1] 2 else temp ← XYZ(A[1..n-1]) 3 if temp < A[n] 4 then return temp 5 else return A[n]
请问算法 XYZ 的输出是什么?( )
B:A 数组的最小值。递归返回 min(前 n-1 个的递归结果, A[n]),逐步求全局最小值;A 求和、C 中值(错误,D 求最大值用 max 而非 min,均不符。
1 #include <algorithm> 2 #include <iostream> 3 using namespace std; 4 5 int n; 6 int d[50][2]; 7 int ans; 8 9 void dfs(int n, int sum) { 10 if (n == 1) { 11 ans = max(sum, ans); 12 return; 13 } 14 for (int i = 1; i < n; ++i) { 15 int a = d[i - 1][0], b = d[i - 1][1]; 16 int x = d[i][0], y = d[i][1]; 17 d[i - 1][0] = a + x; 18 d[i - 1][1] = b + y; 19 for (int j = i; j < n - 1; ++j) 20 d[j][0] = d[j + 1][0], d[j][1] = d[j + 1][1]; 21 int s = a + x + abs(b - y); 22 dfs(n - 1, sum + s); 23 for (int j = n - 1; j > i; --j) 24 d[j][0] = d[j - 1][0], d[j][1] = d[j - 1][1]; 25 d[i - 1][0] = a, d[i - 1][1] = b; 26 d[i][0] = x, d[i][1] = y; 27 } 28 } 29 30 int main() { 31 cin >> n; 32 for (int i = 0; i < n; ++i) 33 cin >> d[i][0]; 34 for (int i = 0; i < n; ++i) 35 cin >> d[i][1]; 36 ans = 0; 37 dfs(n, 0); 38 cout << ans << endl; 39 return 0; 40 }
假设输入的 是不超过 的正整数,d[i][0]、d[i][1] 都是不超过 的正整数,完成下面的判断题和单选题。
若输入 为 ,此程序可能会死循环或发生运行错误。( )
(1 分)若输入 为 ,接下来的输入全为 ,则输出为 。( )
(1 分)输出的数一定不小于输入的 d[i][0] 和 d[i][1] 的任意一个。( )
若输入的 为 ,接下来的输入是 个 和 个 ,则输出为( )。
(1 分)若输入的 为 ,接下来的输入是 个 和 个 ,则输出为( )。
(1 分)若输入的 为 ,接下来的输入是 到 ,以及 到 ,则输出为( )。
(1 分)(最小区间覆盖)给出 个区间,第 个区间的左右端点是 。现在要在这些区间中选出若干个,使得区间 被所选区间的并覆盖(即每一个 都在某个所选的区间中)。保证答案存在,求所选区间个数的最小值。
输入第一行包含两个整数 和 (,)。
接下来 行,每行两个整数 、()。
提示:使用贪心法解决这个问题。先用 的时间复杂度排序,然后贪心选择这些区间。
试补全程序。
1 #include <iostream> 2 3 using namespace std; 4 5 const int MAXN = 5000; 6 int n, m; 7 struct segment { int a, b; } A[MAXN]; 8 9 void sort() // 排序 10 { 11 for (int i = 0; i < n; i++) 12 for (int j = 1; j < n; j++) 13 if (①) 14 { 15 segment t = A[j]; 16 ② 17 } 18 } 19 20 int main() 21 { 22 cin >> n >> m; 23 for (int i = 0; i < n; i++) 24 cin >> A[i].a >> A[i].b; 25 sort(); 26 int p = 1; 27 for (int i = 1; i < n; i++) 28 if (③) 29 A[p++] = A[i]; 30 n = p; 31 int ans = 0, r = 0; 32 int q = 0; 33 while (r < m) 34 { 35 while (④) 36 q++; 37 ⑤; 38 ans++; 39 } 40 cout << ans << endl; 41 return 0; 42 }
①处应填( )。
(1 分)②处应填( )。
(1 分)③处应填( )。
(1 分)④处应填( )。
(1 分)⑤处应填( )。
(1 分)在数据压缩编码中的哈夫曼编码方法,在本质上是一种( )的策略。
B:贪心。哈夫曼每次合并频率最小的两棵树,逐步构建最优前缀码,本质是贪心(局部最优达全局最优)。
有四个人要从 点坐一条船过河到 点,船一开始在 点。该船一次最多可坐两个人。已知这四个人中每个人独自坐船的过河时间分别为 、、、,且两个人坐船的过河时间为两人独自过河时间的较大者。则最短( )时间可以让四个人都过河到 点(包括从 点把船开回 点的时间)。
B:15。最优策略:① 1,2 过河(用 2 分钟),1 独自返回(1 分钟)→ 4 分钟;② 3,4 过河(用 8 分钟),2 返回(2 分钟)→ 10 分钟;③ 1,2 再过河(用 2 分钟)→ 12 分钟;再加回程?实际常见策略 1&2→, 1←, 3&4→, 2←, 1&2→ 共 2+1+8+2+2=15 分钟。
(矩形计数)平面上有 个关键点,求有多少个四条边都和 x 轴或者 y 轴平行的矩形,满足四个顶点都是关键点。给出的关键点可能有重复,但完全重合的矩形只计一次。
试补全枚举算法。
1 #include <iostream> 2 3 using namespace std; 4 5 struct point { 6 int x, y, id; 7 }; 8 9 bool equals(point a, point b) { 10 return a.x == b.x && a.y == b.y; 11 } 12 13 bool cmp(point a, point b) { 14 return ①; 15 } 16 17 void sort(point A[], int n) { 18 for (int i = 0; i < n; i++) 19 for (int j = 1; j < n; j++) 20 if (cmp(A[j], A[j - 1])) { 21 point t = A[j]; 22 A[j] = A[j - 1]; 23 A[j - 1] = t; 24 } 25 } 26 27 int unique(point A[], int n) { 28 int t = 0; 29 for (int i = 0; i < n; i++) 30 if (②) 31 A[t++] = A[i]; 32 return t; 33 } 34 35 bool binary_search(point A[], int n, int x, int y) { 36 point p; 37 p.x = x; 38 p.y = y; 39 p.id = n; 40 int a = 0, b = n - 1; 41 while (a < b) { 42 int mid = ③; 43 if (④) 44 a = mid + 1; 45 else 46 b = mid; 47 } 48 return equals(A[a], p); 49 } 50 51 const int MAXN = 1000; 52 point A[MAXN]; 53 54 int main() { 55 int n; 56 cin >> n; 57 for (int i = 0; i < n; i++) { 58 cin >> A[i].x >> A[i].y; 59 A[i].id = i; 60 } 61 sort(A, n); 62 n = unique(A, n); 63 int ans = 0; 64 for (int i = 0; i < n; i++) 65 for (int j = 0; j < n; j++) 66 if (⑤ && binary_search(A, n, A[i].x, A[j].y) && binary_search(A, n, A[j].x, A[i].y)) { 67 ans++; 68 } 69 cout << ans << endl; 70 return 0; 71 }
①处应填( )
(1 分)②处应填( )
(1 分)③处应填( )
(1 分)④处应填( )
(1 分)⑤处应填( )
(1 分)1 #include <iostream> 2 3 using namespace std; 4 5 int n, k; 6 7 int solve1() 8 { 9 int l = 0, r = n; 10 while (l <= r) { 11 int mid = (l + r) / 2; 12 if (mid * mid <= n) l = mid + 1; 13 else r = mid - 1; 14 } 15 return l - 1; 16 } 17 18 double solve2(double x) 19 { 20 if (x == 0) return x; 21 for (int i = 0; i < k; i++) 22 x = (x + n / x) / 2; 23 return x; 24 } 25 26 int main() 27 { 28 cin >> n >> k; 29 double ans = solve2(solve1()); 30 cout << ans << ' ' << (ans * ans == n) << endl; 31 return 0; 32 }
假设 int 为 位有符号整数类型,输入的 n 是不超过 的自然数、k 是不超过 int 表示范围的自然数,
该算法最准确的时间复杂度分析结果为 。( )
(1 分)当输入为 9801 1 时,输出的第一个数为 99。( )
对于任意输入的 n,随着所输入 k 的增大,输出的第二个数会变成 1。( )
该程序有存在缺陷。当输入的 n 过大时,第 行的乘法有可能溢出,因此应当将 mid 强制转换为 位整数再计算。( )
当输入为 2 1 时,输出的第一个数最接近( )。
当输入为 3 10 时,输出的第一个数最接近( )。
当输入为 256 11 时,输出的第一个数( )。
试补全程序。
1 #include <iostream> 2 #include <vector> 3 4 using namespace std; 5 6 int find_missing(vector<int>& nums) { 7 int left = 0, right = nums.size() - 1; 8 while (left < right) { 9 int mid = left + (right - left) / 2; 10 if (nums[mid] == mid + ①) { 11 ②; 12 } else { 13 ③; 14 } 15 } 16 return ④; 17 } 18 19 int main() { 20 int n; 21 cin >> n; 22 vector<int> nums(n); 23 for (int i = 0; i < n; i++) cin >> nums[i]; 24 int missing_number = find_missing(nums); 25 if (missing_number == ⑤) { 26 cout << "Sequence is consecutive" << endl; 27 } else { 28 cout << "Missing number is " << missing_number << endl; 29 } 30 return 0; 31 }
①处应填( )
(1 分)②处应填( )
(1 分)③处应填( )
(1 分)④处应填( )
(1 分)⑤处应填( )
(1 分)假设有序表中有 1000 个元素,则用二分法查找元素 X 最多需要比较( )次。
B:10。1000 元素二分最多比较 ⌈log₂1000⌉=10(2¹⁰=1024≥1000)。
已知 ,并且对于所有 有 。那么 的值是多少?( )
A:完全二叉树。完全二叉树除最后一层外全满,最后一层左对齐。
1 #include <algorithm> 2 #include <cstdio> 3 #include <cstring> 4 #define ll long long 5 6 int n, k; 7 int a[200007]; 8 int ans[200007]; 9 10 int main() { 11 scanf("%d%d", &n, &k); 12 for (int i = 1; i <= n; ++i) { 13 scanf("%d", &a[i]); 14 } 15 std::sort(a + 1, a + n + 1); 16 n = std::unique(a + 1, a + n + 1) - a - 1; 17 for (int i = 1, j = 0; i <= n; ++i) { 18 for (; j < i && a[i] - a[j + 1] > k; ++j) 19 ; 20 ans[i] = ans[j] + 1; 21 } 22 printf("%d\n", ans[n]); 23 return 0; 24 }
当输入为 3 1 3 2 1 时,输出结果为 。( )
假设输入的 n 为正整数,输出的答案一定满足 且 。( )
将第 行的:
1 n = std::unique(a + 1, a + n + 1) - a - 1;
删除后,有可能出现与原本代码不同的输出结果。( )
(1 分)假设输入的 a 数组和 k 均为正整数,执行第 行代码时,一定满足的条件 不包括( )。
当输入为:n = 100, k = 2, a = {1, 2, ..., 100} 时,输出为( )。
假设输入的 a 数组和 k 均为正整数,但 a 数组不一定有序,则若误删去第 行的:
std::sort(a + 1, a + n + 1);
程序有可能出现的问题有( )。
(1 分)(精明与糊涂)有 个人,分为两类:
i) 精明人:永远能正确判断其他人是精明还是糊涂。
ii) 糊涂人:判断不可靠,会给出随机的判断。
已知精明人严格占据多数,即如果精明人有 个,则满足 。
你只能通过函数 query(i, j) 让第 个人判断第 个人:返回 true 表示判断结果为“精明人”;返回 false 表示判断结果为“糊涂人”。你的目标是,通过这些互相判断,找出至少一个百分之百能确定的精明人。同时,你无需关心 query(i, j) 的内部实现。
以下程序利用“精明人占多数”的优势。设想一个“消除”的过程,让人们互相判断并进行抵消。经过若干轮抵消后,最终留下的候选者必然属于多数派,即精明人。
例如,假设有三个人 、、。如果 说 是糊涂人,而 也说 是糊涂人,则 和 至少有一个是糊涂人。程序将同时淘汰 和 。由于三人里至少有两个精明人,我们确定 是精明人。试补全程序。
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 int N; 6 bool query(int i, int j); 7 8 int main() { 9 cin >> N; 10 11 int candidate = 0; 12 int count = ___①___; 13 14 for (int i = 1; i < N; ++i) { 15 if (___②___) { 16 candidate = i; 17 count = 1; 18 } else { 19 if (___③___) { 20 ___④___; 21 } else { 22 count++; 23 } 24 } 25 } 26 27 cout << ___⑤___ << endl; 28 return 0; 29 }
①处应填( )
(1 分)②处应填( )
(1 分)③处应填( )
(1 分)④处应填( )
(1 分)⑤处应填( )
(1 分)