#P2731. 第1题-镜像字符串
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 82
            Accepted: 33
            Difficulty: 3
            
          
          
          
                       所属公司 : 
                              美团
                                
            
                        
              时间 :2025年3月22日-算法岗
                              
                      
          
 
- 
                        算法标签>暴力枚举          
 
第1题-镜像字符串
题解
题目描述
给定一个字符串 s,你需要找出字符串中所有长度大于1且可镜像的子串的数量。
一个字符串是可镜像的当且仅当满足以下两个条件:
- 它是回文串,即正读和反读是一样的。
 - 它的每个字符都是可镜像字符(即具有垂直对称轴的字符)。
 
可镜像的大写字母有:A、H、I、M、O、T、U、V、W、X、Y。
思路分析
这道题的关键在于找到所有符合条件的子串,首先通过暴力枚举所有长度大于1的子串,然后判断每个子串是否为回文串,再检查它的每个字符是否属于可镜像字符集合。只有当一个子串既是回文串又包含所有可镜像字符时,才算是有效的子串。通过双重循环枚举子串,结合回文判断和字符检查,我们可以得到最终结果。
- 回文串的判断:回文串的判断可以通过将字符串与其反转进行比较来实现。
 - 镜像字符的判断:镜像字符集已知,字符串中的字符需要在这些字符集中,才能判断为可镜像字符。
 - 暴力枚举所有子串:遍历所有长度大于1的子串,判断该子串是否是回文且所有字符是否都在镜像字符集内。
 
C++
#include <iostream>
#include <string>
#include <unordered_set>
using namespace std;
int main() {
    string s;
    cin >> s;
    // 可镜像的字符集合
    unordered_set<char> mirrorChars = {'A', 'H', 'I', 'M', 'O', 'T', 'U', 'V', 'W', 'X', 'Y'};
    
    int n = s.size();
    int count = 0;
    // 枚举所有长度大于1的子串
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            string sub = s.substr(i, j - i + 1);
            
            // 判断是否为回文串
            bool isPalindrome = true;
            int len = sub.size();
            for (int k = 0; k < len / 2; ++k) {
                if (sub[k] != sub[len - k - 1]) {
                    isPalindrome = false;
                    break;
                }
            }
            
            // 判断是否所有字符都是镜像字符
            bool isMirror = true;
            for (char c : sub) {
                if (mirrorChars.find(c) == mirrorChars.end()) {
                    isMirror = false;
                    break;
                }
            }
            // 如果是回文且所有字符都是镜像字符,则计数
            if (isPalindrome && isMirror) {
                ++count;
            }
        }
    }
    cout << count << endl;
    return 0;
}
Python
def count_mirror_substrings(s):
    # 可镜像字符集合
    mirror_chars = {'A', 'H', 'I', 'M', 'O', 'T', 'U', 'V', 'W', 'X', 'Y'}
    n = len(s)
    count = 0
    
    # 枚举所有长度大于1的子串
    for i in range(n):
        for j in range(i + 1, n):
            sub = s[i:j+1]
            
            # 判断是否为回文串
            if sub == sub[::-1]:
                # 判断是否所有字符都是镜像字符
                if all(c in mirror_chars for c in sub):
                    count += 1
    
    return count
# 输入并输出结果
s = input()
print(count_mirror_substrings(s))
Java
import java.util.HashSet;
import java.util.Set;
public class Main {
    public static void main(String[] args) {
        java.util.Scanner sc = new java.util.Scanner(System.in);
        String s = sc.next();
        
        // 可镜像字符集合
        Set<Character> mirrorChars = new HashSet<>();
        for (char c : new char[] {'A', 'H', 'I', 'M', 'O', 'T', 'U', 'V', 'W', 'X', 'Y'}) {
            mirrorChars.add(c);
        }
        
        int n = s.length();
        int count = 0;
        // 枚举所有长度大于1的子串
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                String sub = s.substring(i, j + 1);
                
                // 判断是否为回文串
                StringBuilder reversed = new StringBuilder(sub).reverse();
                if (sub.equals(reversed.toString())) {
                    // 判断是否所有字符都是镜像字符
                    boolean isMirror = true;
                    for (char c : sub.toCharArray()) {
                        if (!mirrorChars.contains(c)) {
                            isMirror = false;
                            break;
                        }
                    }
                    if (isMirror) {
                        count++;
                    }
                }
            }
        }
        
        System.out.println(count);
    }
}
        题目内容
小美有一个长度为n的字符串s,她想知道这个字符串有多少个长度大于1的子串是可镜像的。
可镜像的意思是:一个字符串是回文串,且其中每个字符都有垂直对称轴。
[回文串]一个字符串被称作回文串,当且仅当这个字符串从左往右读和从右往左读是相同的。
有垂直对称轴的大写字母:'A','H','T', 'M', 'O', 'T', 'U','V', 'W', 'X', 'Y'。
输入描述
输入一个长度为n的字符串s,字符串中仅包含大写字母。
1≦n≦100
输出描述
输出一个整数,表示字符串s中长度大于1的可镜像的子串的数量
样例1
输入
AHHAMTT
输出
3
说明
一共3个长度大于1的可镜像的子串:"HH","AHHA","TT"