欢乐赛51题解(这只是个人分析请勿抄袭!
2025-07-07 13:48:26
发布于:福建
题干信息解读
题目描述了一个简化版的石头剪刀布游戏
使用特定字符表示手势:
'Y':剪刀
'O':石头
'C':布
已知对手出的是石头('O')
要求输出能战胜石头的对应字符
整体做题思路
回忆石头剪刀布的基本规则:
布包石头
石头砸剪刀
剪刀剪布
根据题目给定的字符映射关系:
要战胜石头('O'),需要出布('C')
因此直接输出字符'C'即可获胜
题目中的难点和注意事项
主要难点:
理解题目自定义的字符映射关系
确保输出的是获胜手势而非平局手势
注意事项:
输出必须严格是单个字符'C'
不能有多余的空格或换行
注意字符大小写(题目要求大写字母)
#include <bits/stdc++。h>//万能头还是那么万能
using namespace std;
int main() {
// 根据游戏规则,布('C')能赢石头('O')
// 所以直接输出字符'C'即可获胜
cout << 'C';
return 0; // 程序正常结束
}
复杂度分析
时间复杂度:O(1)
仅执行一次输出操作
空间复杂度:O(1)
没有使用任何额外存储空间
程序特点:
执行效率极高
内存占用极小
完全符合题目要求的1秒时间限制和128MB内存限制
题干信息解读
题目描述了一个分档打折的促销活动,折扣规则如下:
≤100元:8折
101-300元:9折
301-500元:原价
500元:15折(注意这是1.5倍价格)
输入一个整数n表示原价,输出打折后保留1位小数的价格
8折=80%=0.8
9折=9%=0.9
15折=150%=1.5
题目中的难点和注意事项
主要难点:
理解"15折"是1.5倍价格(容易误解为85折)
确保浮点数计算的精度
注意事项:
边界值处理(如刚好100、300、500元时)
输出格式必须严格保留1位小数
#include <bits/stdc++.h> // 用于控制输出格式
using namespace std;
int main() {
int n;
cin >> n; // 读取原始价格
double yuan; // 最终价格
// 根据价格区间应用不同折扣
if (n <= 100) {
yuan = n * 0.8; // 8折
} else if (n <= 300) {
yuan= n * 0.9; // 9折
} else if (n <= 500) {
yuan = n; // 原价
} else {
yuan = n * 1.5; // 15折
}
// 输出保留1位小数
cout << fixed << setprecision(1) << yuan;
return 0;
}
复杂度分析
时间复杂度:O(1)
只有简单的条件判断和算术运算
空间复杂度:O(1)
只使用了固定数量的变量
程序特点:
执行效率高
内存占用小
完全符合题目要求的1秒时间限制和128MB内存限制
这个题目主要考察条件判断和基本输入输出处理能力
题干信息解读
题目要求统计给定小写字母字符串中"ac"子串的出现次数。
子串定义为字符串中任意连续字符组成的序列,如"acxgpuamkx"中只有1个"ac"子串。
整体做题思路
遍历字符串检查每个字符及其下一个字符是否组成"ac"
使用计数器记录匹配次数
注意字符串边界条件(避免越界访问)
题目中的难点和注意事项
主要难点:
正确处理字符串边界(最后一个字符不能作为起始字符)
理解子串必须是连续字符
注意事项:
输入字符串长度范围1-1000
输出必须是整数
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s; // 读取输入字符串
int count = 0; // 计数器初始化
// 遍历字符串,检查每个字符和下一个字符
for (int i = 0; i < s.length() - 1; i++) {
if (s[i] == 'a' && s[i+1] == 'c') {
count++; // 找到ac子串则计数
}
}
cout << count; // 输出结果
return 0;
}
复杂度分析
时间复杂度:O(n)
只需一次遍历字符串
空间复杂度:O(1)
仅使用固定数量的变量
程序特点:
高效处理最大1000长度的输入
严格满足1秒时间限制和128MB内存限制
题干信息解读
题目要求对给定小数进行四舍五入处理,保留指定位数的小数。输入包括小数位数n、小数x字符串和保留位数m,输出保留m位后的结果。
整体做题思路
处理输入数据:读取n、x和m
定位小数点位置,提取小数部分
根据m+1位的数字决定是否进位
处理可能的连续进位情况
输出保留m位的结果
题目中的难点和注意事项
主要难点:
正确处理连续进位(如0.999保留2位变为1.00)
字符串操作时索引处理
注意事项:
输入范围:1≤n≤1000,m≤n
输出必须严格保留m位小数
需要考虑四舍五入后整数部分变化的情况
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m; // n:小数位数 m:保留位数
string x; // 存储输入的小数字符串
cin >> n >> x >> m; // 读取输入数据
// 检查是否需要四舍五入(当保留位数小于总位数且下一位≥5时)
if (m < n && x[m+2] >= '5') {
int pos = m+1; // 从保留的最后一位开始处理进位
// 向前遍历处理进位
while (pos >= 2) { // 2对应小数点后的第一位
if (x[pos] == '.') { // 跳过小数点
pos--;
continue;
}
if (x[pos] < '9') { // 当前位可以+1
x[pos]++;
break;
} else { // 当前位是9需要进位
x[pos] = '0';
pos--; // 继续处理前一位
}
}
}
// 输出结果(保留m位小数,包含"0."共m+2位)
cout << x.substr(0, m+2) << endl;
return 0;
}
时间复杂度分析
输入读取:O(1) - 固定3次输入操作
四舍五入处理:
最坏情况:O(m) - 需要处理所有m位进位(如0.999...9保留m位)
平均情况:O(1) - 通常只需处理1-2位进位
字符串截取:O(m) - substr操作需要复制m+2个字符
总时间复杂度:O(m) (由最耗时的进位处理和字符串截取决定)
空间复杂度分析
输入存储:O(n) - 存储原始字符串
处理过程:O(1) - 仅使用固定数量的变量
输出结果:O(m) - 存储结果子串
总空间复杂度:O(n) (由输入字符串长度决定)
题干信息解读
题目要求统计n×n矩阵中满足条件的"bingo"数量。bingo定义为:任意行、列或两条对角线(主对角线和副对角线)上的数字之和为奇数。输入包括矩阵大小n和矩阵元素,输出满足条件的直线数量。
整体做题思路
输入矩阵数据
检查所有行、列和对角线的和是否为奇数
统计满足条件的直线数量
输出结果
题目中的难点和注意事项
难点:
正确处理大矩阵(n≤1000)的输入输出
准确计算两条对角线的和
注意事项:
矩阵元素范围0≤a[i][j]≤5000
时间复杂度需控制在O(n²)以内
空间复杂度需考虑n≤1000的限制
#include <bits/stdc++.h>
using namespace std;
const int MAX_SIZE = 2000; // 定义最大矩阵尺寸
int main() {
int n; // 矩阵大小n×n
cin >> n;
int gr[MAX_SIZE][MAX_SIZE]; // 存储矩阵数据
// 输入矩阵数据
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> gr[i][j];
}
}
int bingoCnt = 0; // 记录bingo数量
// 检查每一行
for (int i = 0; i < n; i++) {
int rSum = 0; // 行和
for (int j = 0; j < n; j++) {
rSum += gr[i][j];
}
if (rSum % 2 != 0) { // 和为奇数则计数
bingoCnt++;
}
}
// 检查每一列
for (int j = 0; j < n; j++) {
int cSum = 0; // 列和
for (int i = 0; i < n; i++) {
cSum += gr[i][j];
}
if (cSum % 2 != 0) { // 和为奇数则计数
bingoCnt++;
}
}
// 检查主对角线
int diag1Sum = 0; // 主对角线
for (int i = 0; i < n; i++) {
diag1Sum += gr[i][i];
}
if (diag1Sum % 2 != 0) { // 和为奇数则计数
bingoCnt++;
}
// 检查副对角线
int di2Sum = 0; // 副对角线
for (int i = 0; i < n; i++) {
di2Sum += gr[i][n - 1 - i];
}
if (di2Sum % 2 != 0) { // 和为奇数则计数
bingoCnt++;
}
cout << bingoCnt << endl; // 输出结果
return 0;
}
复杂度分析
时间复杂度:O(n²)
输入数据:O(n²)
行检查:O(n²)
列检查:O(n²)
对角线检查:O(n)
总计:O(n²)
空间复杂度:O(n²)
存储矩阵:O(n²)
其他变量:O(1)
题干信息解读
题目要求找出数组中所有差值为3的倍数的数对中的最大差值。输入包括数组长度n和数组元素,输出符合条件的最大差值。例如输入[1,100,2,900],最大差值为100-1=99。
整体做题思路
将数组元素按模3的结果分组(余0、1、2)
记录每组的最小值和最大值
计算各组内最大值与最小值的差
取三个差值中的最大值作为结果
题目中的难点和注意事项
难点:
理解数对差值为3的倍数的数学性质(a≡b mod 3)
处理大数组(n≤100000)的高效算法
注意事项:
元素范围0≤a[i]≤1000
时间复杂度需控制在O(n)以内
空间复杂度需考虑n≤100000的限制
#include <bits/stdc++.h>
using namespace std;
int main() {
int n; // 数组长度
cin >> n;
// 初始化三个余数分组的最小值和最大值
// 余0组:[0], 余1组:[1], 余2组:[2]
int minal[3] = {1001, 1001, 1001}; // 初始化为比最大值大的数
int mx[3] = {-1, -1, -1}; // 初始化为比最小值小的数
// 遍历数组元素
for (int i = 0; i < n; i++) {
int a; // 当前元素
cin >> a;
int r = a % 3; // 计算余数
// 更新当前余数组的最小值
if (a < minal[r]) {
minal[r] = a;
}
// 更新当前余数组的最大值
if (a > mx[r]) {
mx[r] = a;
}
}
// 计算各组内最大值与最小值的差
int di0 = mx[0] - minal[0]; // 余0组的差值
int di1 = mx[1] - minal[1]; // 余1组的差值
int di2 = mx[2] - minal[2]; // 余2组的差值
// 取三个差值中的最大值
int ans = max(di0, max(di1, di2));
cout << ans << endl;
return 0;
}
杂度分析
时间复杂度:O(n)
输入数据:O(n)
分组处理:O(n)
差值计算:O(1)
总计:O(n)
空间复杂度:O(1)
固定大小的数组存储分组信息
其他变量:O(1)
以上为个人思路,请以官方为准。
制作不易给个赞吧
这里空空如也
有帮助,赞一个