校招算法笔面试 | 校招笔面试真题-密码破译

题目## 题目

题目链接

题解

题目难度:中等

知识点:ASCII码、递归、DFS

解题思路:首先,这道题一看就主要考察DFS,使用递归就可以求解出题。然后,因为涉及到数字和字符的转换,这个自然就会联想到ASCII码。整体思路还是比较清晰的,主要还需要考虑涉及到一些特殊情况。首先,“0”这个数字在转换过程中需要怎么考虑。因为不可能单独存在一个“0”进行转换,所以必须让它和之前的字符合并起来进行计算;然后,还需要考虑到字母的数量极限,因为一共有26个字母,所以这里一旦数字大于26时,是必须拆分的,只能作为一个单独位进行处理。所以,在考虑完这些情况后,整体思路就比较清晰了。

#include<iostream>
#include<string>
#include<vector>
using namespace std;
//创建一个方法来实现破解
void DFS(string s,int i,string res,vector<string> &tmp)
{
    if(i==s.size()-1)
    {
        res+=char(s[i]+48);
        tmp.push_back(res);
        return;
    }
    if(i>s.size()-1)
    {
        tmp.push_back(res);
        return;
    }
    //一共26个字母,所以以26为界
    if((s[i]-48)*10+(s[i+1]-48)>26)
    {
        res+=char(s[i]+48);
        DFS(s,i+1,res,tmp);
    }
    else{
        string temp=res;
        res+=char(s[i]+48);
        //如果下一位是'0',则不能单独作为一位来分割
        if(s[i+1]!='0')
            DFS(s,i+1,res,tmp);
        res=temp+char(((s[i]-48)*10+(s[i+1]-48))+96);
        //这里还有一个特殊情况,如果剩下s[i+2]为'0'时,也会出现对'0'进行破解的局面
        //此外,还要考虑当i==s.size()-2时,i+2是否已经越界
        if(i==s.size()-2)
            DFS(s,i+2,res,tmp);
        else if(s[i+2]!='0')
            DFS(s,i+2,res,tmp);
    }
     
}
int main()
{
    string s;
    while(cin>>s)
    {
        vector<string> secret;
        DFS(s,0,"",secret);
        for(int i=0;i<secret.size();i++)
        {
            cout<<secret[i]<<' ';
        }
        cout<<endl;
    }
}

题目链接

解题思路

这是一道密码验证题目,需要检查以下条件:

  1. 密码规则:

    • 只能由大写字母、小写字母、数字构成
    • 不能以数字开头
    • 必须至少包含两种字符类型
    • 长度至少为8
  2. 验证步骤:

    • 检查长度是否大于等于8
    • 检查首字符是否为数字
    • 统计各类字符数量
    • 检查是否包含非法字符
    • 检查字符类型是否满足要求

代码

#include <iostream>
#include <string>
using namespace std;

bool checkPassword(const string& pwd) {
    // 检查长度
    if (pwd.length() < 8) return false;
    
    // 检查首字符
    if (isdigit(pwd[0])) return false;
    
    // 统计字符
    int upper = 0, lower = 0, digit = 0;
    
    for (char c : pwd) {
        if (isupper(c)) upper++;
        else if (islower(c)) lower++;
        else if (isdigit(c)) digit++;
        else return false;  // 非法字符
    }
    
    // 检查字符类型数量
    int types = (upper > 0) + (lower > 0) + (digit > 0);
    return types >= 2;
}

int main() {
    int n;
    cin >> n;
    
    while (n--) {
        string pwd;
        cin >> pwd;
        cout << (checkPassword(pwd) ? "YES" : "NO") << endl;
    }
    return 0;
}
import java.util.Scanner;

public class Main {
    public static boolean checkPassword(String pwd) {
        // 检查长度
        if (pwd.length() < 8) return false;
        
        // 检查首字符
        if (Character.isDigit(pwd.charAt(0))) return false;
        
        // 统计字符
        int upper = 0, lower = 0, digit = 0;
        
        for (char c : pwd.toCharArray()) {
            if (Character.isUpperCase(c)) upper++;
            else if (Character.isLowerCase(c)) lower++;
            else if (Character.isDigit(c)) digit++;
            else return false;  // 非法字符
        }
        
        // 检查字符类型数量
        int types = (upper > 0 ? 1 : 0) + (lower > 0 ? 1 : 0) + (digit > 0 ? 1 : 0);
        return types >= 2;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        
        while (n-- > 0) {
            String pwd = sc.next();
            System.out.println(checkPassword(pwd) ? "YES" : "NO");
        }
    }
}
def check_password(pwd):
    # 检查长度
    if len(pwd) < 8:
        return False
        
    # 检查首字符
    if pwd[0].isdigit():
        return False
        
    # 统计字符
    upper = sum(1 for c in pwd if c.isupper())
    lower = sum(1 for c in pwd if c.islower())
    digit = sum(1 for c in pwd if c.isdigit())
    
    # 检查是否包含非法字符
    if len(pwd) != upper + lower + digit:
        return False
        
    # 检查字符类型数量
    types = (upper > 0) + (lower > 0) + (digit > 0)
    return types >= 2

def main():
    n = int(input())
    for _ in range(n):
        pwd = input().strip()
        print("YES" if check_password(pwd) else "NO")

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法:字符串处理
  • 时间复杂度: O ( n × L ) \mathcal{O}(n \times L) O(n×L) - n n n 为密码数量, L L L 为密码长度
  • 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 只需要常数级别的额外空间
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值