题解 | #密码强度等级#

密码强度等级

http://www.nowcoder.com/practice/52d382c2a7164767bca2064c1c9d5361

题意

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

限制:密码长度不大于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)

全部评论

相关推荐

06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
06-26 15:33
青岛工学院 Java
积极的秋田犬要冲国企:他现在邀请我明天面试
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-11 15:08
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务