欢迎大家订阅我的专栏:蓝桥青少C++ Python题解!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力蓝桥杯青少组竞赛备战!
专栏特色
1.经典算法练习:根据蓝桥杯青少组竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。
适合人群:
- 准备参加蓝桥杯青少组竞赛的学生
- 希望系统学习C++/Python编程的初学者
- 想要提升算法与编程能力的编程爱好者
附上汇总贴:历年CSP-J初赛真题解析 | 汇总-CSDN博客
#include <iostream>
#include <vector>
using namespace std;
int find_missing(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] == mid + ①) {
②;
} else {
③;
}
}
return ④;
}
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) cin >> nums[i];
int missing_number = find_missing(nums);
if (missing_number == ⑤) {
cout << "Sequence is consecutive" << endl;
} else {
cout << "Missing number is " << missing_number << endl;
}
return 0;
}
33、①处应填( )
A.1
B.nums[0]
C.right
D.left
【答案】:B
【解析】
第9行可以判断出代码为二分搜索,所以第11行和第13行肯定是left和right两个指针的移动,故第10行应该是判断满足什么条件时,left指针需要移动。mid左侧为连续的数字时,left需要移动。num[mid]= mid+num[0]时,左侧数字是连续的,选B。
可以代入nums = [1,2,3,5,6]进行验算,第一次while循环,mid = 2,nums[2] == 3,满足nums[mid] == mid + num[0](3 == 2 + 1)。
34、②处应填( )
A.left = mid + 1
B.right = mid - 1
C.right = mid
D.left = mid
【答案】:A
【解析】
mid左侧数据满足连续时,left指针需要移到mid的右侧,所以A选项left = mid+1满足。
35、③处应填( )
A.left = mid + 1
B.right = mid - 1
C.right = mid
D.left = mid
【答案】:C
【解析】
mid左侧数据不连续,则右侧数据肯定连续。因此需要把right指针改为mid,下一轮从mid的左侧区域开始查找。所以选C
36、④处应填( )
A.left + nums[0]
B.right + nums[0]
C.mid + nums[0]
D.right + 1
【答案】:A
【解析】
当退出while循环时,一定是left指针指向那个被移除的数前面一个数,用left+nums[0]就可以得到被移除的数,所以选A。
37、⑤处应填( )
A.nums[0] + n
B.nums[0] + n - 1
C.nums[0] + n + 1
D.nums[n-1]
【答案】:D
【解析】
题目描述中提到“除非被移除的是第一个或最后一个元素”,所以要打印“Sequence is consecutive”,只可能移除第一个或最后一个元素,4个选项D为最后一个元素,所以选D
(编辑距离)给定两个字符串, 每次操作可以选择删除(Delete)、插入(Insert)、替换(Replace),一个字符, 求将第一个字符串转换为第二个字符串所需要的最少操作次数。
试补全动态规划算法。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int min(int x, int y, int z) {
return min(min(x, y), z); //三个整数求最小值
}
int edit_dist_dp(string str1, string str2) {
int m = str1.length(); //str1的长度
int n = str2.length(); //str2的长度
vector<vector<int>> dp(m + 1, vector<int>(n + 1)); //创建一个二维数组dp
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= n; j++) {
if (i == 0)
dp[i][j] = ①;
else if (j == 0)
dp[i][j] = ②;
else if (③)
dp[i][j] = ④;
else
dp[i][j] = 1 + min(dp[i][j - 1], dp[i - 1][j], ⑤);
}
}
return dp[m][n];
}
int main() {
string str1, str2;
cin >> str1 >> str2;
cout << "Minimum number of operations: "
<< edit_dist_dp(str1, str2) << endl;
return 0;
}
38、①处应填( )
A.j
B.i
C.m
D.n
【答案】:A
【解析】
dp[m][n]表示长度为m的字符串变成长度为n的字符串最少步数,那么dp[0][j]就应该表示str1长度为0的字符串变成长度为j的字符串最少步数。显然应该是添加j个字符,所以选A
39、②处应填( )
A.j
B.i
C.m
D.n
【答案】:B
【解析】
同39题,dp[m][n]表示长度为m的字符串变成长度为n的字符串最少步数,那么dp[i][0]就应该表示str1长度为i的字符串变成长度为0的字符串最少步数。显然应该是删除i个字符,所以选B
40、③处应填( )
A.str1[i - 1] == str2[j - 1]
B.str1[i] == str2[j]
C.str1[i - 1] != str2[j - 1]
D.stri[i] != str2[j]
【答案】:A
【解析】
因为第24行应该是判断str1和str2某个位置字符不相等时的处理,故这里就应该是字符相等的位置。str1和str2的第i个字符应该是str1[i-1],选A
41、④处应填( )
A.dp[i - 1][j - 1] + 1
B.dp[i - 1][j - 1]
C.dp[i - 1][j]
D.dp[i][j - 1]
【答案】:B
【解析】
这里是动态规划的基本概念,如果两个字符相等,str1的i字符变成str2的j个字符最少步数,就等于str的i-1个字符变成str2的j-1个字符的最少步数。选B
42、⑤处应填( )
A.dp[i][j] + 1
B.dp[i - 1][j - 1] + 1
C.dp[i - 1][j - 1]
D.dp[i][j]
【答案】:C
【解析】
3个数字应该分别对应着插入、删除和替换。插入的话,就是相当于i比j多1,dp[i][j-1]就对应着插入。删除的话,就是相当于i比j少1,dp[i-1][j]就对应着删除。替换的话,i和j的数量相等,C选项满足要求。
5个空选出来后,可以带入abc和abd字符进行验算。打表如下:
i 0 1 2 3
j 0 0 1 2 3
1 1 0 1 2
2 2 1 0 1
3 3 2 1 1