题目链接
题目描述
根据一系列规则为给定的密码计算一个安全分数,并根据分数评定其安全等级。
计分规则:
-
密码长度
个字符: 5 分
到
个字符: 10 分
个字符: 25 分
-
字母
- 没有字母: 0 分
- 全都是小写或全都是大写: 10 分
- 大小写混合: 20 分
-
数字
- 没有数字: 0 分
- 1 个数字: 10 分
个数字: 20 分
-
符号
- 没有符号: 0 分
- 1 个符号: 10 分
个符号: 25 分
-
奖励 (取最高奖励,不累加)
- 字母和数字: +2 分
- 字母、数字和符号: +3 分
- 大小写字母、数字和符号: +5 分
等级划分:
: 非常安全 (VERY_SECURE)
: 安全 (SECURE)
: 非常强 (VERY_STRONG)
: 强 (STRONG)
: 一般 (AVERAGE)
: 弱 (WEAK)
: 非常弱 (VERY_WEAK)
解题思路
这是一个纯粹的模拟题,核心在于将题目中描述的计分规则准确地翻译成代码。我们需要设计一个函数或一段逻辑,能够 meticulously 地检查密码的各项指标,并累加分数。
算法流程:
-
预处理:
- 读取输入的密码字符串。
- 遍历一次字符串,统计以下信息:
- 密码的
length
(总长度)。 lower_case_count
(小写字母个数)。upper_case_count
(大写字母个数)。digit_count
(数字个数)。symbol_count
(符号个数)。
- 密码的
-
分项计分:
- 初始化
total_score = 0
。 - 长度分:根据
length
的值,使用if-else
判断,将 5, 10, 或 25 加到total_score
。 - 字母分:
- 如果
lower_case_count > 0
且upper_case_count > 0
,则为大小写混合,加 20 分。 - 如果
lower_case_count > 0
或upper_case_count > 0
(但不满足上一条),则为单一大小写,加 10 分。 - 否则,没有字母,加 0 分。
- 如果
- 数字分:根据
digit_count
的值 (0, 1, 或 >1),将 0, 10, 或 20 加到total_score
。 - 符号分:根据
symbol_count
的值 (0, 1, 或 >1),将 0, 10, 或 25 加到total_score
。 - 奖励分:
- 设置一些布尔标记,如
has_letter
,has_digit
,has_symbol
,has_mixed_case
。 - 这是一个有优先级的奖励,所以从最高奖励开始判断:
- 如果
has_mixed_case
且has_digit
且has_symbol
,加 5 分。 - 否则,如果
has_letter
且has_digit
且has_symbol
,加 3 分。 - 否则,如果
has_letter
且has_digit
,加 2 分。
- 如果
- 设置一些布尔标记,如
- 初始化
-
评定等级:
- 根据最终的
total_score
,使用if-else
从高到低判断其所属的区间,并输出对应的安全等级字符串。
- 根据最终的
代码
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
// 检查字符是否为符号
bool isSymbol(char c) {
return !isalnum(c);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
string password;
while (cin >> password) {
int score = 0;
int len = password.length();
int lower_count = 0, upper_count = 0, digit_count = 0, symbol_count = 0;
for (char c : password) {
if (islower(c)) lower_count++;
else if (isupper(c)) upper_count++;
else if (isdigit(c)) digit_count++;
else symbol_count++;
}
// 1. 长度分
if (len <= 4) score += 5;
else if (len <= 7) score += 10;
else score += 25;
// 2. 字母分
if (lower_count > 0 && upper_count > 0) score += 20;
else if (lower_count > 0 || upper_count > 0) score += 10;
// 3. 数字分
if (digit_count == 1) score += 10;
else if (digit_count > 1) score += 20;
// 4. 符号分
if (symbol_count == 1) score += 10;
else if (symbol_count > 1) score += 25;
// 5. 奖励分
bool has_letter = (lower_count > 0 || upper_count > 0);
bool has_mixed = (lower_count > 0 && upper_count > 0);
bool has_digit = (digit_count > 0);
bool has_symbol = (symbol_count > 0);
if (has_mixed && has_digit && has_symbol) score += 5;
else if (has_letter && has_digit && has_symbol) score += 3;
else if (has_letter && has_digit) score += 2;
// 评定等级
if (score >= 90) cout << "VERY_SECURE" << endl;
else if (score >= 80) cout << "SECURE" << endl;
else if (score >= 70) cout << "VERY_STRONG" << endl;
else if (score >= 60) cout << "STRONG" << endl;
else if (score >= 50) cout << "AVERAGE" << endl;
else if (score >= 25) cout << "WEAK" << endl;
else cout << "VERY_WEAK" << endl;
}
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
String password = sc.nextLine();
int score = 0;
int len = password.length();
int lowerCount = 0, upperCount = 0, digitCount = 0, symbolCount = 0;
for (char c : password.toCharArray()) {
if (Character.isLowerCase(c)) lowerCount++;
else if (Character.isUpperCase(c)) upperCount++;
else if (Character.isDigit(c)) digitCount++;
else symbolCount++;
}
// 1. 长度分
if (len <= 4) score += 5;
else if (len <= 7) score += 10;
else score += 25;
// 2. 字母分
if (lowerCount > 0 && upperCount > 0) score += 20;
else if (lowerCount > 0 || upperCount > 0) score += 10;
// 3. 数字分
if (digitCount == 1) score += 10;
else if (digitCount > 1) score += 20;
// 4. 符号分
if (symbolCount == 1) score += 10;
else if (symbolCount > 1) score += 25;
// 5. 奖励分
boolean hasLetter = (lowerCount > 0 || upperCount > 0);
boolean hasMixed = (lowerCount > 0 && upperCount > 0);
boolean hasDigit = (digitCount > 0);
boolean hasSymbol = (symbolCount > 0);
if (hasMixed && hasDigit && hasSymbol) score += 5;
else if (hasLetter && hasDigit && hasSymbol) score += 3;
else if (hasLetter && hasDigit) score += 2;
// 评定等级
if (score >= 90) System.out.println("VERY_SECURE");
else if (score >= 80) System.out.println("SECURE");
else if (score >= 70) System.out.println("VERY_STRONG");
else if (score >= 60) System.out.println("STRONG");
else if (score >= 50) System.out.println("AVERAGE");
else if (score >= 25) System.out.println("WEAK");
else System.out.println("VERY_WEAK");
}
}
}
import sys
def solve():
for line in sys.stdin:
password = line.strip()
if not password:
continue
score = 0
length = len(password)
lower_count, upper_count, digit_count, symbol_count = 0, 0, 0, 0
for char in password:
if 'a' <= char <= 'z':
lower_count += 1
elif 'A' <= char <= 'Z':
upper_count += 1
elif '0' <= char <= '9':
digit_count += 1
else:
symbol_count += 1
# 1. 长度分
if length <= 4:
score += 5
elif length <= 7:
score += 10
else:
score += 25
# 2. 字母分
if lower_count > 0 and upper_count > 0:
score += 20
elif lower_count > 0 or upper_count > 0:
score += 10
# 3. 数字分
if digit_count == 1:
score += 10
elif digit_count > 1:
score += 20
# 4. 符号分
if symbol_count == 1:
score += 10
elif symbol_count > 1:
score += 25
# 5. 奖励分
has_letter = (lower_count > 0 or upper_count > 0)
has_mixed = (lower_count > 0 and upper_count > 0)
has_digit = (digit_count > 0)
has_symbol = (symbol_count > 0)
if has_mixed and has_digit and has_symbol:
score += 5
elif has_letter and has_digit and has_symbol:
score += 3
elif has_letter and has_digit:
score += 2
# 评定等级
if score >= 90:
print("VERY_SECURE")
elif score >= 80:
print("SECURE")
elif score >= 70:
print("VERY_STRONG")
elif score >= 60:
print("STRONG")
elif score >= 50:
print("AVERAGE")
elif score >= 25:
print("WEAK")
else:
print("VERY_WEAK")
solve()
算法及复杂度
-
算法:模拟
-
时间复杂度:
,其中
是输入密码的长度。我们需要遍历一次密码字符串来统计各类字符的数量,后续的计分和评级都是常数时间操作。
-
空间复杂度:
。除了存储输入的密码字符串外,我们只需要有限的几个变量来存储计数和分数,因此空间复杂度是常数。