题意

给定了一系列密码规则,根据这套规则得出密码的总分,不同总分输出不同提示

限制:密码长度不大于300

规则

题目直接给出的就是规则

一、密码长度:

5 分: 小于等于4 个字符

10 分: 5 到7 字符

25 分: 大于等于8 个字符

二、字母:

0 分: 没有字母

10 分: 全都是小(大)写字母

20 分: 大小写混合字母

三、数字:

0 分: 没有数字

10 分: 1 个数字

20 分: 大于1 个数字

四、符号:

0 分: 没有符号

10 分: 1 个符号

25 分: 大于1 个符号

五、奖励:

2 分: 字母和数字

3 分: 字母、数字和符号

5 分: 大小写字母、数字和符号

最后的评分标准:

>= 90: 非常安全

>= 80: 安全(Secure)

>= 70: 非常强

>= 60: 强(Strong)

>= 50: 一般(Average)

>= 25: 弱(Weak)

>= 0: 非常弱

方法

翻译实现

直接把题目逐字逐句翻译成代码

代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    char s[310];
    while(~scanf("%s",s)){ // 读入字符串
        int c = 0; // 累计得分
        
        int n = strlen(s); // 字符串长度
        if(n < 5) c+=5; // 小于等于4 个字符
        else if(n < 8)c+=10; // 5 到7 字符
        else c+=25;
        
        bool la = false; // 小写字母是否存在
        bool ua = false; // 大写字母是否存在
        int num = 0; // 数字出现次数
        int sig = 0; // 符号出现次数
        for(int i = 0;i < n;i++){
            la = la || islower(s[i]); // 小写字母
            ua = ua || isupper(s[i]); // 大写字母
            num += isdigit(s[i]); // 数字
            if( 
                (s[i] >= 0x21 && s[i] <= 0x2f) || 
                (s[i] >= 0x3a && s[i] <= 0x40) || 
                (s[i] >= 0x5b && s[i] <= 0x60) || 
                (s[i] >= 0x7b && s[i] <= 0x7e)
                ){ // 符号
                sig ++;
            }
        }
        if(la && ua) c+=20; // 大小写混合字母
        else if(la || ua) c+=10; // 全都是小(大)写字母
        else c+=0;
        
        if(num > 1) c+=20; // 大于1 个数字
        else if(num == 1) c+=10; // 1 个数字
        else c+=0;
        
        if(sig > 1) c+=25; // 大于1 个符号
        else if(sig == 1) c+=10; // 1 个符号
        else c+=0;
        
        if(sig && num && la && ua) c+= 5; // 大小写字母、数字和符号
        else if(sig && num && (la || ua)) c+=3; // 字母、数字和符号
        else if(num && (la || ua)) c+=2; // 字母和数字
        
        if(c >= 90) printf("VERY_SECURE\n");
        else if(c>=80) printf("SECURE\n");
        else if(c>=70) printf("VERY_STRONG\n");
        else if(c>=60) printf("STRONG\n");
        else if(c>=50) printf("AVERAGE\n");
        else if(c>=25) printf("WEAK\n");
        else if(c>=0) printf("VERY_WEAK\n");
        
    }
    return 0;
}

复杂度分析

时间复杂度: 对于字符串遍历过程,操作为常数代价,剩余部分判断都是常数代价,所以时间复杂度为O(n)O(n)

空间复杂度: 主要消耗在字符串存储,空间复杂度为O(n)O(n)

ASCII优化

注意到这里虽然题目提供了ASCII码的具体数值,但是实际上在C++可以直接把char与int进行比较,会让char变为其ascii值。因此这里我们可以直接书写其实和结束的字符,而不需要知道它的具体值

alt

alt

alt

alt

代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    char s[310];
    while(~scanf("%s",s)){
        int c = 0;
        
        int n = strlen(s);
        if(n < 5) c+=5; // 小于等于4 个字符
        else if(n < 8)c+=10; // 5 到7 字符
        else c+=25;
        
        bool la = false;
        bool ua = false;
        int num = 0;
        int sig = 0;
        for(int i = 0;i < n;i++){
            la = la || islower(s[i]); // 小写字母
            ua = ua || isupper(s[i]); // 大写字母
            num += isdigit(s[i]); // 数字
            if(  //  直接使用字符而不是数值
                (s[i] >= '!' && s[i] <= '/') || 
                (s[i] >= ':' && s[i] <= '@') || 
                (s[i] >= '[' && s[i] <= '`') || 
                (s[i] >= '{' && s[i] <= '~')
                ){ // 符号
                sig ++;
            }
        }
        if(la && ua) c+=20; // 大小写混合字母
        else if(la || ua) c+=10; // 全都是小(大)写字母
        else c+=0;
        
        if(num > 1) c+=20; // 大于1 个数字
        else if(num == 1) c+=10; // 1 个数字
        else c+=0;
        
        if(sig > 1) c+=25; // 大于1 个符号
        else if(sig == 1) c+=10; // 1 个符号
        else c+=0;
        
        if(sig && num && la && ua) c+= 5; // 大小写字母、数字和符号
        else if(sig && num && (la || ua)) c+=3; // 字母、数字和符号
        else if(num && (la || ua)) c+=2; // 字母和数字 
      
        if(c >= 90) printf("VERY_SECURE\n");
        else if(c>=80) printf("SECURE\n");
        else if(c>=70) printf("VERY_STRONG\n");
        else if(c>=60) printf("STRONG\n");
        else if(c>=50) printf("AVERAGE\n");
        else if(c>=25) printf("WEAK\n");
        else if(c>=0) printf("VERY_WEAK\n");
        
    }
    return 0;
}

复杂度分析

时间复杂度: 对于字符串遍历过程,操作为常数代价,剩余部分判断都是常数代价,所以时间复杂度为O(n)O(n)

空间复杂度: 主要消耗在字符串存储,空间复杂度为O(n)O(n)