首页 > 试题广场 >

卡中心密码安全规范

[编程题]卡中心密码安全规范
  • 热度指数:1441 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
小明在卡中心工作,用到的很多系统账号都需要设置安全密码。密码如果符合以下规范可以称为安全密码:
1、密码至少包含6个字符,至多包含20个字符;
2、至少包含一个小写字母,至少包含一个大写字母,至少包含一个数字;
3、不能出现连续3个相同的字符。

请写一个检查密码是否为安全密码的函数。
输入为一个字符串作为密码,输出为将该密码改为安全密码的最小改变次数。如果它已经是安全密码,则返回0。
备注:插入、删除、或者替换一个字符,均视为改变一次。

输入描述:
输入为一个字符串作为密码。


输出描述:
输出为将该密码改为安全密码的最小改变次数。如果它已经是安全密码,则返回0。
示例1

输入

aB3ab3

输出

0
示例2

输入

aaaaaa

输出

2
示例3

输入

abcdefG

输出

1
感觉这道题就是把各种情况都考虑到了就可以做出来了,但是情况很多,代码也很长,这种题,真的应该用在笔试中吗
发表于 2020-07-20 11:19:54 回复(1)
1.题目没说清楚,应该是不能出现3个连续相同的字符(不是字母!导致我第一次WA了)
2.说下思路吧,其实挺简单的,就是自己没想清楚就开始敲了,还是要打好草稿再开始写
(1)首先遍历一次算出题目条件123的满足情况;
(2)当字符串长度len<6时,条件2缺啥加个啥就行,条件3就中间插入一个字符把相同的顺序打乱;所以比较分别满足3个条件的改变次数,选最大的输出就好了;
(3)当6<=len<=20,条件二字符交换缺啥换啥,条件3换把相同字符最后一个换成其他字符,不用加减字符所以条件1不变,比较条件2条件3改变次数,选最大的输出;
(4)当len>20时,首先必须要把字符串减到20,这个操作的次数是不能省的,但是减些就有考究 了,这里优先减AAA这种情况,减掉一个变成AA刚好也满足条件3,然后再减AAAA四个连续相同的情况,这时就要减2个才能满足了,最后再减AAAAA这种,要减3个字符。当字符串满足条件了,这个时候转到第三步一样做就行了
3.这个题字符串不长,只要想清楚不管啥算法都能过,我自己改来改去底下代码写的太烂了大佬们就没看了
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
int len,i,j,ans,res3,res2,res1,res4,res5,res6;
bool n,d,x;
char s[1000];
gets(s);
len=strlen(s);
n=d=x=0;
res3=res4=res5=res6=0;
j=-1;
for(i=0;i<len;i++)
{
if('A'<=s[i]&&s[i]<='Z'&&d==0)
{
d=1;
}
if('a'<=s[i]&&s[i]<='z'&&x==0)
{
x=1;
}
if('0'<=s[i]&&s[i]<='9'&&n==0)
{
n=1;
}
if(i>=2)
{
if(s[i]==s[i-1]&&s[i]==s[i-2]&&s[i]==s[i+1]&&s[i]==s[i+2]&&i<len-2)
{
if(i-j>=3)
{
res6++;
}
}
if(s[i]==s[i-1]&&s[i]==s[i-2]&&s[i]==s[i+1]&&i<len-1)
{
if(i-j>=3)
{
res5++;
}
}
if(s[i]==s[i-1]&&s[i]==s[i-2])
{
if(i-j>=3)
{
res3++;
j=i;
}
res4++;
}
}
}
res2=0;
res3=res3-res5;
res5=res5-res6;
if(d==0)    res2++;
if(x==0)    res2++;
if(n==0)    res2++;
if(len<6)
{
res1=6-len;
ans=max(res1,res3+res5+res6);
ans=max(ans,res2);
}
else
{
if(len>20)
{
res1=len-20;
//printf("%d %d\n",res1,res4);
if(res1>=res4)
{
ans=res1+res2;
}
else
{
if(res3>=res1)
{
if(res2<=(res3+res5+res6-res1))
{
ans=res3+res5+res6;
}
else
{
ans=res1+res2;
}
}
else
{
ans=res3;
res1=res1-res3;
for(;res1>0;)
{
if(res5>0&&res1>=2)
{
res1=res1-2;
res5--;
ans=ans+2;
}
if(res1==1)
{
ans++;
res1=0;
}
if(res1==2&&res5==0)
{
ans=ans+2;
res1=0;
}
if(res6>0&&res1>=3)
{
res1=res1-3;
res6--;
ans=ans+3;
}
}
if(res2<=res6+res5)
{
ans=ans+res6+res5;
}
else
{
ans=ans+res2;
}
}
}
}
else
{
res1=0;
ans=max(res1,res3+res5+res6);
ans=max(ans,res2);
}
}
printf("%d\n",ans);
return 0;
}

编辑于 2019-02-13 13:28:45 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    string s;
    cin>>s;
    int n=s.length(), l=0, u=0, m=0, t=0, k=0, sum=0;
    for(int i=0;i<s.length();i++){
        if(t>0 && s[i]==s[i-1]){
            t++;
            if(t==3){
                sum++;
                if(n>20){
                    n--;
                    t = 2;
                }else{
                    t = 0;
                    k++;
                }
            }
        }else
            t = 1;
        if(islower(s[i]))
            l = 1;
        else if(isupper(s[i]))
            u = 1;
        else if(isdigit(s[i]))
            m = 1;        
    }
    t = 3-l-u-m;
    t = max(t-k, 0);
    if(n < 6)
        sum += max(6-n, t);
    else if(n > 20)
        sum += n - 20 + t;
    else
        sum += t;
    printf("%d\n", sum);
    return 0;
}

发表于 2020-10-23 01:13:42 回复(0)
这个题是leetcode第420题原题,面向业务编程,主要思路是分类讨论,但极其复杂,不具备太大的算法练习价值。
class Solution:
    def strongPasswordChecker(self, password: str) -> int:
        n = len(password)
        has_lower = has_upper = has_digit = False
        for ch in password:
            if ch.islower():
                has_lower = True
            elif ch.isupper():
                has_upper = True
            elif ch.isdigit():
                has_digit = True
        categories = has_lower + has_upper + has_digit
        if n < 6:
            return max(6 - n, 3 - categories)
        elif n <= 20:
            replace = cnt = 0
            cur = "#"
            for ch in password:
                if ch == cur:
                    cnt += 1
                else:
                    replace += cnt // 3
                    cnt = 1
                    cur = ch
            replace += cnt // 3
            return max(replace, 3 - categories)
        else:
            # 替换次数和删除次数
            replace, remove = 0, n - 20
            # k mod 3 = 1 的组数,即删除 2 个字符可以减少 1 次替换操作
            rm2 = cnt = 0
            cur = "#"
            for ch in password:
                if ch == cur:
                    cnt += 1
                else:
                    if remove > 0 and cnt >= 3:
                        if cnt % 3 == 0:
                            # 如果是 k % 3 = 0 的组,那么优先删除 1 个字符,减少 1 次替换操作
                            remove -= 1
                            replace -= 1
                        elif cnt % 3 == 1:
                            # 如果是 k % 3 = 1 的组,那么存下来备用
                            rm2 += 1
                        # k % 3 = 2 的组无需显式考虑
                    replace += cnt // 3
                    cnt = 1
                    cur = ch
            if remove > 0 and cnt >= 3:
                if cnt % 3 == 0:
                    remove -= 1
                    replace -= 1
                elif cnt % 3 == 1:
                    rm2 += 1
            replace += cnt // 3
            # 使用 k % 3 = 1 的组的数量,由剩余的替换次数、组数和剩余的删除次数共同决定
            use2 = min(replace, rm2, remove // 2)
            replace -= use2
            remove -= use2 * 2
            # 由于每有一次替换次数就一定有 3 个连续相同的字符(k / 3 决定),因此这里可以直接计算出使用 k % 3 = 2 的组的数量
            use3 = min(replace, remove // 3)
            replace -= use3
            remove -= use3 * 3
            return (n - 20) + max(replace, 3 - categories)

if __name__ == "__main__":
    print(Solution().strongPasswordChecker(input()))
最后附上一张本题的经典评论来讽刺此题

发表于 2022-04-11 16:11:01 回复(2)
#!/usr/bin/env python 
# -*- coding:utf-8 -*-
def distinct(c):
    x=distinct2(c)
    y=distinct3(c)
    if len(c)<6:
       p=6-len(c)
       if x<=y:
        count=p+y
       else:
        count=p+x
    if len(c)>=6 and len(c)<=20:
        if x<=y:
            count=y
        else:
            count=x
    if len(c)>20:
        q=len(c)-20
        ch=[]
        for i in range(20):
            ch.append(c[i])
        x=distinct2(ch)
        y=distinct3(ch)
        if x<=y:
          count=q+y
        else:
          count=q+x
    return  count
def distinct2(c):
    a=0
    h=[0,0,0,0]
    for i in c:
        if i>='a' and i<='z':
            h[0]+=1
        elif i>='A' and i<='Z':
            h[1]+=1
        elif i>='0' and i<='9':
            h[2]+=1
        elif i=='.':
            h[3]+= 1
    for j in h:
        if j==0:
            a+=1
    return a
def distinct3(c):
     b,d=0,0
     m=1
     for i in range(len(c)):
         if i-1>=0 and c[i]==c[i-1]:
              m+=1
              if m>=3:
                b=m//3
         else:
             d+=b
             m=1
             b=0
     if m>=3:
        d=m//3+d
     return  d
if __name__=='__main__':
    l=list(input('input:'))
    l=distinct(l)
    print(l)

发表于 2019-10-19 20:14:31 回复(0)
借鉴了cx123的思路,写了python代码
# -*- coding: utf-8 -*-
"""
Created on Mon May 13 15:04:16 2019

@author: i
"""

if __name__ == "__main__":
    
    s = raw_input()
    n = len(s)
    lower = 0
    upper = 0
    number = 0
    
    stack = []
    stack1 = []
    stack2 = []
    for i in range(n):
        if len(stack) < 2:
            stack.append(s[i])
        else:
            if s[i]!=stack[-1] or s[i]!=stack[-2]:
                stack.append(s[i])
            else:
                stack.append("marker")
                stack.append(s[i])
        
        if len(stack1) < 2:
            stack1.append(s[i])
        else:
            if s[i]!=stack1[-1] or s[i]!=stack1[-2]:
                stack1.append(s[i])
            else:
                stack1.append("marker")
        
        if s[i]>="a" and s[i]<="z":
            lower += 1
        elif s[i]>="A" and s[i]<="Z":
            upper += 1
        elif s[i]>="0" and s[i]<="9":
            number += 1
    
    #print " ".join(stack1)
    if n<6:
        times1 = 6-n   
        times2 = 0
        if lower<1:
            times2+=1
        if upper<1:
            times2+=1
        if number<1:
            times2+=1  
        times3 = sum([1 for item in stack if item == "marker"])
        result = max(times1,times2,times3)
    elif n>=6 and n<=20:
        times2 = 0
        if lower<1:
            times2+=1
        if upper<1:
            times2+=1
        if number<1:
            times2+=1
            
        times3 = sum([1 for item in stack1 if item == "marker"])
        result = max(times2,times3)
    else:
        f = 0
        result = 0
        flag = 0
        pos = [[] for i in range(3)]
        for i in range(n-1,1,-1):
            if stack1[i] == "marker":
                if i == n-1:
                    pos[0].append(i)
                elif i == n-2:
                    if stack1[i+1] == stack1[i-1]:
                        pos[1].append(i)
                    else:
                        pos[0].append(i)
                else:
                    if stack1[i+2] == stack1[i-1] and stack1[i+1] == stack1[i-1]:
                        pos[2].append(i)
                    elif stack1[i+1] == stack1[i-1]:
                        pos[1].append(i)
                    else:
                        pos[0].append(i)
        
        while True:
            if len(pos[0])!=0:
                i = pos[0][-1]
                pos[0].pop()
                stack1 = stack1[0:i]+["delete"]+stack1[i+1:n]
                f+=1
            elif len(pos[1])!=0:
                i = pos[1][-1]
                pos[1].pop()
                stack1 = stack1[0:i]+["delete"]*2+stack1[i+2:n]
                f+=2
            elif len(pos[2])!=0:
                i = pos[2][-1]
                pos[2].pop()
                stack1 = stack1[0:i]+["delete"]*3+stack1[i+3:n]
                f+=3
            #print " ".join(stack1)
            if n-f<23:
                break
    
        if n-f == 21:
            if len(pos[0])>=1:
                i = pos[0][0]
                stack1 = stack1[0:i]+["delete"]+stack1[i+1:n]
        elif n-f == 22:
            if len(pos[0])>=2:
                i = pos[0][0]
                stack1 = stack1[0:i]+["delete"]+stack1[i+1:n]
                i = pos[0][1]
                stack1 = stack1[0:i]+["delete"]+stack1[i+1:n]
            elif len(pos[1])>=1:
                i = pos[1][0]
                stack1 = stack1[0:i]+["delete"]*2+stack1[i+2:n]
            elif len(pos[0])>=1:
                i = pos[0][0]
                stack1 = stack1[0:i]+["delete"]+stack1[i+1:n]
        
        ms = [item for item in stack1 if item!="delete"]
            
        times1 = max(n-20,n-len(ms))
        times2 = 0
        if lower<1:
            times2+=1
        if upper<1:
            times2+=1
        if number<1:
            times2+=1
        times3 =  sum([1 for item in ms if item == "marker"])
        result = max(times1+times2,times1+times3)
    
    print result

发表于 2019-05-13 20:10:33 回复(0)
import java.util.Scanner;

public class Main{

static int count = 0;

public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.nextLine();
char[] c = str.toCharArray();
int n = distinct(c);
System.out.println(n);
}

public static int distinct(char[] c) {
int x = distinct2(c);
int y = distinct3(c);
if(c.length < 6) {
int p = 6 - c.length;
if(x <= y ) {
count = p + y;
}else {
count = p + x;
}
}
if(c.length >= 6 && c.length <= 20) {
if(x <= y ) {
count = y;
}else {
count = x;
}
}
if(c.length > 20) {
int q = c.length - 20;
char[] ch = new char[20];
for (int i = 0; i < ch.length; i++) {
ch[i] = c[i];
}

x = distinct2(ch);
//y = distinct3("6$$$$$$$$$$54321####".toCharArray());
y = distinct3(ch);
if(x <= y ) {
count = q + y;
}else {
count = q + x;
}
}
return count;
}

public static int distinct2(char[] c) {
int a = 0;
int[] h = {0,0,0};
for (char d : c) {
if(d >= 'a' && d <= 'z' ) {
h[0] ++;
}else if(d >= 'A' && d <= 'Z') {
h[1] ++;
}else {
h[2] ++;
}
}
for (int i : h) {
if (i == 0) {
a++;
}
}

return a;
}
public static int distinct3(char[] c) {
int b = 0;
int d = 0;
int m = 1;
for (int i = 0; i < c.length; i++) {
if(i-1 >=0 && c[i] == c[i-1] ) {
m++;
if(m >= 3 ) {
b = m / 3;
}
}else {
d += b;
m = 1;
b = 0;
}
}
if(m >= 3) {
d = m/3 + d ;
}
return d;
}
}
编辑于 2018-08-13 21:15:57 回复(7)