20250322 c++gesp三级编程题答案
题目传送门(B4261 [GESP202503 三级] 2025)
题目传送门(B4262 [GESP202503 三级] 词频统计)
思路(B4261 [GESP202503 三级] 2025):
整体思路
本题的目标是找出满足等式 (x and y)+(x or y)=2025
的最小正整数 y
。这里的 and
是二进制按位与运算(在 C++ 里用 &
表示),or
是二进制按位或运算(在 C++ 里用 |
表示)。为了求解,采用枚举法,把所有可能的正整数 y
都遍历一遍,检查是否满足给定等式。
详细步骤
-
输入读取:
- 借助
cin
从标准输入读取整数x
。这个x
是题中给定的已知整数。
- 借助
-
枚举
y
的值:- 利用
for
循环从1
开始逐个枚举y
的值,上限设为2024
。之所以上限设为2024
,是因为x
的范围是0 ≤ x < 2025
,而且y
是正整数,所以y
只要在1
到2024
这个区间内枚举就可以。
- 利用
-
检查等式是否成立:
- 对于每一个枚举到的
y
值,计算(x & y) + (x | y)
的结果。 - 把计算结果和
2025
进行比较,若相等,就说明找到了满足条件的y
。
- 对于每一个枚举到的
-
输出结果:
- 一旦找到满足条件的
y
,就使用cout
把y
输出到标准输出,然后结束程序。 - 要是遍历完
1
到2024
所有可能的y
值,都没有找到满足条件的,就输出-1
,以此表明不存在符合条件的y
。
- 一旦找到满足条件的
代码优化思路
此代码采用的是枚举法,时间复杂度为 O(n),这里的 n 是枚举的范围(本题是 2024
)。由于枚举范围比较小,所以当前代码效率还可以。要是枚举范围变大,这种方法效率就会降低。可以考虑从位运算的特性出发进行优化,不过本题数据范围较小,当前的枚举法已经足够高效。
思路(B4262 [GESP202503 三级] 词频统计):
这是一道关于统计单词出现频率并找出出现次数最多单词的题目,解题的关键在于处理单词的大小写问题以及有效地统计每个单词的出现次数。以下是详细的解题思路:
-
读取输入的单词数量:
- 首先从输入中读取一个整数
n
,它表示接下来要输入的单词个数。可以使用cin
来读取这个整数。
- 首先从输入中读取一个整数
-
存储和统计单词出现次数:
- 为了忽略单词的大小写,我们可以将所有输入的单词都转换为小写形式。可以使用
transform
函数结合tolower
函数来实现这一转换。 - 采用
unordered_map
来存储每个单词及其出现的次数。unordered_map
的键是单词(小写形式),值是该单词出现的次数。 - 循环读取
n
个单词,每次读取一个单词后,将其转换为小写形式,然后在unordered_map
中查找该单词。如果单词已经存在于unordered_map
中,则将其对应的值(出现次数)加 1;如果单词不存在,则在unordered_map
中插入该单词,并将其出现次数初始化为 1。
- 为了忽略单词的大小写,我们可以将所有输入的单词都转换为小写形式。可以使用
-
找出出现次数最多的单词:
- 遍历
unordered_map
,通过比较每个单词的出现次数,找到出现次数最多的单词。可以定义一个变量来记录当前出现次数最多的单词及其出现次数。 - 遍历
unordered_map
时,对于每个键值对,将其值(出现次数)与当前记录的最大出现次数进行比较。如果当前单词的出现次数大于最大出现次数,则更新最大出现次数和对应的单词。
- 遍历
-
输出结果:
- 最后,输出出现次数最多的单词(以小写形式)。可以使用
cout
来输出该单词。
- 最后,输出出现次数最多的单词(以小写形式)。可以使用
通过以上步骤,就可以实现对输入单词的频率统计,并找出出现次数最多的单词。
代码&解释(由于为c++考级,所以没有其他语言):
B4261 [GESP202503 三级] 2025:
#include <iostream>
using namespace std;
const int MAX_Y = 2025;
int main() {
int x;
cin >> x;
int possible_y[MAX_Y];
for (int i = 0; i < MAX_Y; i++) {
possible_y[i] = i + 1;
}
for (int i = 0; i < MAX_Y; i++) {
int y = possible_y[i];
if ((x & y) + (x | y) == 2025) {
cout << y << endl;
return 0;
}
}
cout << -1 << endl;
return 0;
}
代码思路
- 输入读取:使用
cin
从标准输入读取整数x
。 - 创建数组:定义一个长度为
MAX_Y
的数组possible_y
,并将1
到MAX_Y
的整数依次存入数组中。这里数组的作用主要是存储所有可能的y
值。 - 遍历数组:对数组进行遍历,对于每个
y
值,计算(x & y) + (x | y)
的结果,并与2025
进行比较。 - 输出结果:如果找到满足条件的
y
,则输出该y
并结束程序;若遍历完数组都未找到满足条件的y
,则输出-1
。
复杂度分析
- 时间复杂度:O(n),其中 n 为数组的长度(这里是
MAX_Y
),因为需要遍历整个数组。 - 空间复杂度:O(n),主要用于存储数组
possible_y
。
但是本题似乎数据简单,所以还有一种更简便的写法:
#include<iostream>
#include<string>
#include<algorithm>
#include<bitset>
#include<cmath>
#include<iomanip>
#include<cstdio>
#include<cstring>
using namespace std;
int x,y;
int main(){
cin>>x;
cout<<2025 - x;
return 0;
}
B4262 [GESP202503 三级] 词频统计:
#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>
using namespace std;
// 将单词转换为小写形式
string toLowerCase(const string& word) {
string lowerCaseWord = word;
transform(lowerCaseWord.begin(), lowerCaseWord.end(), lowerCaseWord.begin(), ::tolower);
return lowerCaseWord;
}
int main() {
int n;
cin >> n;
cin.ignore();
unordered_map<string, int> wordCount;
string maxWord;
int maxCount = 0;
for (int i = 0; i < n; ++i) {
string word;
getline(cin, word);
string lowerCaseWord = toLowerCase(word);
// 统计单词出现次数
++wordCount[lowerCaseWord];
// 更新出现次数最多的单词
if (wordCount[lowerCaseWord] > maxCount) {
maxCount = wordCount[lowerCaseWord];
maxWord = lowerCaseWord;
}
}
cout << maxWord << endl;
return 0;
}
代码说明
- 命名空间简化:借助
using namespace std;
,代码里能够直接运用标准库中的类型(像string
、unordered_map
)和函数(如cin
、cout
、transform
),而无需添加std::
前缀。 - 功能实现:和之前的代码逻辑一样,先是把输入的单词转换为小写形式,再用
unordered_map
统计每个单词的出现次数,最后找出出现次数最多的单词并输出。