算法题详细解析 + 代码 + 注释
算法题详细解析 + 代码 + 注释
📌 第20题:密码验证程序
题目要求
-
密码长度必须 大于 8 位。
-
必须包含 至少三种字符类型:
- 大写字母
- 小写字母
- 数字
- 其他符号
-
不能存在长度大于 2 的重复子串。
思路分析
- 检查长度是否 > 8。
- 统计 4 种字符类别,至少出现 3 种。
- 遍历所有长度为 3 的子串,判断是否有重复。
C++ 实现(详细注释)
#include <iostream>
#include <string>
#include <cctype> // isupper, islower, isdigit
using namespace std;// 检查密码是否符合要求
bool checkPassword(const string &pw) {// 1. 长度判断if (pw.size() <= 8) return false;// 2. 统计字符种类bool hasUpper = false, hasLower = false, hasDigit = false, hasOther = false;for (char ch : pw) {if (isupper(ch)) hasUpper = true; // 大写字母else if (islower(ch)) hasLower = true; // 小写字母else if (isdigit(ch)) hasDigit = true; // 数字else hasOther = true; // 其他字符}int typeCount = hasUpper + hasLower + hasDigit + hasOther;if (typeCount < 3) return false; // 至少 3 种字符类型// 3. 检查长度为3的重复子串for (size_t i = 0; i < pw.size() - 2; ++i) {string sub = pw.substr(i, 3); // 取出长度为3的子串// 如果在后面找到相同的子串,说明重复if (pw.find(sub, i + 1) != string::npos) {return false;}}return true;
}int main() {string s;// 支持多组输入while (cin >> s) {cout << (checkPassword(s) ? "OK" : "NG") << endl;}return 0;
}
📌 第21题:简单密码加密
加密规则
- 小写字母 → 手机九宫格数字(a-c:2, d-f:3, … z:9)
- 大写字母 → 转小写后后移一位(Z→a)
- 数字和其他符号保持不变
C++ 实现(详细注释)
#include <iostream>
#include <string>
#include <cctype> // tolower
using namespace std;// 小写字母转数字(九宫格规则)
char lowerToNum(char ch) {if (ch >= 'a' && ch <= 'c') return '2';if (ch >= 'd' && ch <= 'f') return '3';if (ch >= 'g' && ch <= 'i') return '4';if (ch >= 'j' && ch <= 'l') return '5';if (ch >= 'm' && ch <= 'o') return '6';if (ch >= 'p' && ch <= 's') return '7';if (ch >= 't' && ch <= 'v') return '8';if (ch >= 'w' && ch <= 'z') return '9';return ch;
}// 加密函数
string encrypt(const string &s) {string res;for (char ch : s) {if (islower(ch)) {// 小写字母 → 数字res += lowerToNum(ch);} else if (isupper(ch)) {// 大写字母 → 转小写后 +1char lower = tolower(ch);char shifted = (lower == 'z') ? 'a' : lower + 1;res += shifted;} else {// 数字或符号 → 原样输出res += ch;}}return res;
}int main() {string s;while (getline(cin, s)) { // 读取整行cout << encrypt(s) << endl;}return 0;
}
📌 第22题:汽水瓶兑换
规则
- 3 个空瓶换 1 瓶汽水。
- 剩 2 个空瓶可借 1 个再换 1 瓶。
C++ 实现(详细注释)
#include <iostream>
using namespace std;// 计算最多能喝多少瓶汽水
int maxSoda(int n) {int total = 0;while (n >= 3) {total += n / 3; // 兑换汽水n = n / 3 + n % 3; // 新空瓶 + 余瓶}// 特殊情况:剩 2 瓶 → 借 1 瓶if (n == 2) total += 1;return total;
}int main() {int n;while (cin >> n && n != 0) { // 输入 0 结束cout << maxSoda(n) << endl;}return 0;
}
📌 第23题:删除出现次数最少的字符
题目要求
- 删除出现次数最少的所有字符。
- 多组输入。
C++ 实现(详细注释)
#include <iostream>
#include <string>
#include <vector>
#include <climits> // INT_MAX
using namespace std;int main() {string s;while (cin >> s) {vector<int> freq(256, 0); // 统计 ASCII 字符次数// 1. 统计每个字符出现次数for (char ch : s) {freq[(unsigned char)ch]++;}// 2. 找到最小的出现次数int minCount = INT_MAX;for (int count : freq) {if (count > 0 && count < minCount) {minCount = count;}}// 3. 输出时跳过次数等于 minCount 的字符for (char ch : s) {if (freq[(unsigned char)ch] != minCount) {cout << ch;}}cout << endl;}return 0;
}
⚠️ 注意事项
- 多组输入:
while(cin >> s)
会一直读到 EOF。 - 字符数组:用
(unsigned char)
防止负数索引。 - 效率问题:密码检测重复子串时,
substr
+find
足够 AC。