蓝桥云课—回文字符串

思路是:
1.判断字符串是否是由'q' 'b' 'l'组成的字符串,如果是就直接输出Yes,因为这样的字符串都可以通过往开头添加若干个q' 'b' 'l'组成回文字符串。



2.如果不是第一种情况就把字符串本身去判断是否是回文字符串,如果是就直接输出Yes


3.如果不是就把字符串分成三部分,第一部分是开头包含l、q、b的部分,第二部分是中间不包含l、q、b的部分,第三部分是结尾包含l、q、b的部分。 

然后再去判断第二部分是不是回文字符串,如果不是就直接输出No,因为它不能通过往开头添加使之变成回文字符串了因为它的核心部分就不是回文的,如果第二部分是回文字符串,那就设置两个指针i、j分别指向第一部分的结尾和第三部分的开头,如果指向的字符相等,则i--,j++。如果循环结束了,就有三种情况,1.两指针同时走出界,表明所遍历的字符都相等是回文字符串。(实际这就是本身就是回文字符串的情况)2.如果i先走出界,第一部分先走完,就去遍历第三部分剩余部分,如果剩余部分都是在l、q、b之内的就输出Yes,有一个不属于其中就是No。3.如果j先走出界,表明开头的第一部分还有多余的字符,此时仅有添加操作无论如何也构成不了回文字符串的。输出No

 

 

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        int n=scan.nextInt();
        scan.nextLine();//消耗掉一行
        for(int i=0;i<n;i++)
        {
            String str=scan.nextLine();//接收每一行字符串
            char arr[]=str.toCharArray();//把字符串转换成字符数组
            int k;
            for(k=0;k<arr.length;k++)
            {
              if(arr[k]!='l' && arr[k]!='q' && arr[k]!='b')
              {
                break;
              }
            }
            if(k>=arr.length)
            {
                System.out.println("Yes");
                continue;
            }
            if(reply(arr)==true)//如果本身就是回文字符串直接返回Yes
            {
                System.out.println("Yes");
            }
            else//如果本身不是回文字符串就把原字符串分成三部分
            {
                int start=0;
                int end=arr.length-1;
                while(arr[end]=='l' || arr[end]=='q' || arr[end]=='b')
                {
                    end--;
                }
                char[] sub3=str.substring(end+1,arr.length).toCharArray();//第三部分
                while(arr[start]=='l' || arr[start]=='q' || arr[start]=='b')
                {
                    start++;
                }
                char[] sub1=str.substring(0,start).toCharArray();//第一部分
                char[] sub2=str.substring(start,end+1).toCharArray();//第二部分
                start=sub1.length-1;//为第一部分的结尾
                end=0;//为第三部分的开头
                if(reply(sub2))
                {
                    while(start>=0 && end<=sub3.length-1)
                    {
                        if(sub1[start]!=sub3[end])
                        {
                            System.out.println("No");
                            break;
                        }
                        start--;
                        end++;
                    }
                    if(start>=0)//sub3先走完
                    {
                      System.out.println("No");
                      break;
                    }
                    else//sub1先走完
                    {
                        while(end<=sub3.length-1)
                        {
                            if(sub3[end]!='l' && sub3[end]!='q' && sub3[end]!='b')
                            {
                                System.out.println("No");
                                break;
                            }
                            end++;
                        }
                        if(end>sub3.length-1)//判断是否是循环走完了
                        {
                          System.out.println("Yes");
                        }
                    }
                }
                else
                {
                    System.out.println("No");//如果第二部分不是回文字符串就直接No
                }
            }
        }
        scan.close();
    }
    public static boolean reply(char[] arr){//检查是否为回文字符串
        int i=0;
        int j=arr.length-1;
        while(i<j)
        {
            if(arr[i]!=arr[j])
                return false;
            i++;
            j--;
        }
        return true;
    }
}
<think>嗯,用户需要关于蓝桥杯竞赛中“合法密码”问题的Python实现和解题思路。首先,我得确定“合法密码”题目的具体要求。通常,这类题目可能有多个条件需要满足,比如长度限制、字符类型组合、特定子串排除等。但用户没有给出具体题目描述,所以可能需要参考常见的类似题目。 记得蓝桥杯的题目通常会有明确的规则,例如密码必须包含大小写字母、数字,长度在某个范围,或者不能有重复字符等。比如,可能要求密码满足以下条件:长度≥8,至少包含一个大写字母、一个小写字母和一个数字,且不能包含连续三个相同的字符。 接下来,我需要考虑如何用Python来验证这些条件。首先,处理输入,可能需要读取多个测试用例。然后,对每个密码字符串进行检查: 1. 长度检查:使用len()函数判断是否≥8。 2. 字符类型检查:遍历每个字符,统计是否包含至少一个大写字母、小写字母和数字。可以用islower(), isupper(), isdigit()方法。 3. 连续字符检查:遍历字符串,检查是否有三个连续相同的字符。例如,可以用循环比较当前字符与前两个是否相同。 另外,需要注意边界情况,比如空字符串、恰好8个字符、刚好满足条件的情况。可能还需要优化性能,但蓝桥杯的测试数据一般不会太大,所以直接遍历应该没问题。 然后,根据用户的引用,引用[3]提到了蓝桥杯备考的必刷题,可能包含类似题目。但用户提到的引用[4]是关于N皇后问题的,可能不太相关。不过引用[1]和[2]可能有相关资源链接,但用户需要具体的解题思路和代码。 可能的错误点:在检查连续三个相同字符时,要注意索引范围,避免越界。例如,从索引2开始检查,比较i、i-1、i-2是否相同。或者使用滑动窗口的方式遍历每三个连续的字符。 然后,编写代码结构大致如下: 读取输入n,然后循环n次读取每个密码,对每个密码进行三个条件的判断,输出YES或NO。 测试用例方面,例如: 输入:2 Abc12345 AAbbcdefg123 第一个符合条件,输出YES;第二个存在连续三个b,输出NO。 再考虑如何处理特殊情况,比如密码中包含特殊字符,但题目可能只要求字母和数字,或者允许其他字符?需要根据题目具体要求调整,但假设题目只要求必须有大写、小写、数字,其他字符不影响存在性,但可能题目有其他限制,需要明确。 如果没有具体题目描述,可能需要基于常见情况给出通用解法,并建议用户参考具体题目要求调整条件。 总结步骤: 1. 输入处理。 2. 检查长度。 3. 检查字符类型是否包含大写、小写、数字。 4. 检查是否有三个连续相同字符。 5. 根据所有条件是否满足输出结果。 可能的优化:使用正则表达式来简化检查,比如用正则匹配是否同时存在大写、小写、数字,以及是否有三个连续重复字符。例如,正则表达式中的正向前瞻和匹配重复的模式。 例如,正则表达式: ^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?!.*(.)\1\2).{8,}$ 但这里可能存在错误,因为正则中的反向引用可能需要正确的方式。正确的检查三个连续相同字符的正则应该是(.)\1{2},即匹配任意字符后跟两个相同的字符。所以整个正则可以写成: ^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?!.*(.)\1{2}).{8,}$ 但正则表达式可能在处理长字符串时效率问题,但对于题目来说足够。 不过,对于Python来说,使用正则可能代码更简洁,但可读性可能稍差。或者用常规的循环检查更直观。 因此,给出两种方法:正则和常规方法,供用户选择。 最后,根据用户提供的引用,特别是引用[3]提到的蓝桥云课有相关题目,可能用户的问题类似回文日期或其他条件组合,但需要按常见情况处理。 综上,整理思路,写出分步的解题思路和示例代码,并生成相关问题。</think>### 蓝桥杯“合法密码”问题 Python 实现与解题思路 #### 问题分析 蓝桥杯竞赛中“合法密码”类题目通常要求验证密码字符串是否满足以下条件(以常见题型为例): 1. **长度≥8** 2. **至少包含大写字母、小写字母、数字各一个** 3. **不能有连续三个相同的字符** #### 解题步骤 1. **输入处理**:读取密码数量 `n` 和每个密码字符串。 2. **条件验证**: - **长度检查**:`len(password) >= 8` - **字符类型检查**:遍历字符串,统计是否包含至少一个大写字母、小写字母和数字。 - **连续字符检查**:遍历字符串,判断是否存在连续三个相同字符。 3. **输出结果**:根据条件满足情况输出 `YES` 或 `NO`。 --- #### Python 实现代码 ```python n = int(input()) for _ in range(n): password = input().strip() valid = True # 条件1: 长度≥8 if len(password) < 8: valid = False # 条件2: 包含大写、小写、数字 has_upper = any(c.isupper() for c in password) has_lower = any(c.islower() for c in password) has_digit = any(c.isdigit() for c in password) if not (has_upper and has_lower and has_digit): valid = False # 条件3: 连续三个相同字符检查 for i in range(2, len(password)): if password[i] == password[i-1] == password[i-2]: valid = False break print("YES" if valid else "NO") ``` --- #### 代码解析 1. **输入处理**:使用 `input()` 读取输入数据。 2. **条件1**:直接通过 `len(password)` 判断长度。 3. **条件2**:通过 `any()` 函数结合字符判断方法快速检查是否包含所需字符类型。 4. **条件3**:从索引2开始遍历,检查当前字符与前两位是否相同。 5. **输出结果**:综合所有条件判断结果,输出最终结论。 --- #### 示例输入与输出 **输入**: ``` 2 Abc12345 AAAbcdefg123 ``` **输出**: ``` YES NO ``` - 第一个密码满足所有条件。 - 第二个密码因 `AAA` 连续三个相同字符失败。 --- #### 优化与扩展 1. **正则表达式实现**:可用正则表达式简化条件验证: ```python import re n = int(input()) pattern = r"^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?!.*(.)\1{2}).{8,}$" for _ in range(n): password = input().strip() print("YES" if re.match(pattern, password) else "NO") ``` - `(?=.*[A-Z])`:正向预查确保存在大写字母。 - `(?!.*(.)\1{2})`:排除连续三个相同字符。 2. **性能优化**:若数据量较大,可提前终止遍历(如发现连续字符后立即跳出循环)[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值