1 条题解

  • 0
    @ 2025-7-15 18:41:00

    方法思路

    要解决这个问题,我们需要将字符串切割成满足条件的子串:长度为不小于3的奇数,且每个子串内部字符全部相同。

    1. 首先将原字符串分解成连续相同字符的子串,例如"aaabbbbbbbb"分解为"aaa"和"bbbbbbbb"。
    2. 对于每个连续相同字符的子串,判断能否切分成符合条件的子串:
      • 如果长度小于3,无法切分,返回-1
      • 如果长度是奇数且大于等于3,可以直接作为一个子串
      • 如果长度是偶数,尝试切分成多个符合条件的子串,例如"bbbbbbbb"可以切分为"bbb"和"bbbbb"
    3. 贪心策略:对于偶数长度的连续子串,尽量先切出长度为3的子串,剩余部分保持为奇数

    代码实现

    Java
    import java.util.*;
    
    public class Main {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            int n = scanner.nextInt();
            scanner.nextLine();  // 消耗换行符
            String s = scanner.nextLine();
            
            List<String> result = new ArrayList<>();
            int i = 0;
            
            while (i < n) {
                char c = s.charAt(i);
                int j = i;
                
                // 找到连续相同字符的子串
                while (j < n && s.charAt(j) == c) {
                    j++;
                }
                
                int length = j - i;
                if (length < 3) {
                    System.out.println(-1);
                    return;
                }
                
                List<String> segments = splitSegment(s.substring(i, j));
                if (segments == null) {
                    System.out.println(-1);
                    return;
                }
                
                result.addAll(segments);
                i = j;
            }
            
            System.out.println(String.join(" ", result));
        }
        
        private static List<String> splitSegment(String segment) {
            List<String> result = new ArrayList<>();
            char c = segment.charAt(0);
            int length = segment.length();
            
            if (length < 3) {
                return null;
            }
            
            if (length % 2 == 1) {
                // 奇数长度,直接添加
                result.add(segment);
            } else {
                // 偶数长度,需要切分
                int remaining = length;
                
                // 如果长度是偶数,先切出一个长度为3的子串
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 3; i++) {
                    sb.append(c);
                }
                result.add(sb.toString());
                remaining -= 3;
                
                // 剩余部分如果是奇数且大于等于3,可以直接添加
                if (remaining >= 3) {
                    sb = new StringBuilder();
                    for (int i = 0; i < remaining; i++) {
                        sb.append(c);
                    }
                    result.add(sb.toString());
                } else if (remaining > 0) {
                    // 剩余部分小于3,无法切分
                    return null;
                }
            }
            
            return result;
        }
    }
    
    
    Python
    def split_string(s):
        result = []
        i = 0
        n = len(s)
        
        while i < n:
            c = s[i]
            j = i
            
            # 找到连续相同字符的子串
            while j < n and s[j] == c:
                j += 1
            
            length = j - i
            if length < 3:
                return None
            
            segments = split_segment(s[i:j])
            if segments is None:
                return None
            
            result.extend(segments)
            i = j
        
        return result
    
    def split_segment(segment):
        result = []
        c = segment[0]
        length = len(segment)
        
        if length < 3:
            return None
        
        if length % 2 == 1:
            # 奇数长度,直接添加
            result.append(segment)
        else:
            # 偶数长度,需要切分
            remaining = length
            
            # 如果长度是偶数,先切出一个长度为3的子串
            result.append(c * 3)
            remaining -= 3
            
            # 剩余部分如果是奇数且大于等于3,可以直接添加
            if remaining >= 3:
                result.append(c * remaining)
            elif remaining > 0:
                # 剩余部分小于3,无法切分
                return None
        
        return result
    
    n = int(input())
    s = input()
    
    result = split_string(s)
    if result is None:
        print(-1)
    else:
        print(" ".join(result))
    
    
    C++
    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    
    vector<string> splitSegment(const string& segment) {
        vector<string> result;
        char c = segment[0];
        int length = segment.length();
        
        if (length < 3) {
            return {};
        }
        
        if (length % 2 == 1) {
            // 奇数长度,直接添加
            result.push_back(segment);
        } else {
            // 偶数长度,需要切分
            int remaining = length;
            
            // 如果长度是偶数,先切出一个长度为3的子串
            string s(3, c);
            result.push_back(s);
            remaining -= 3;
            
            // 剩余部分如果是奇数且大于等于3,可以直接添加
            if (remaining >= 3) {
                result.push_back(string(remaining, c));
            } else if (remaining > 0) {
                // 剩余部分小于3,无法切分
                return {};
            }
        }
        
        return result;
    }
    
    int main() {
        int n;
        string s;
        cin >> n >> s;
        
        vector<string> result;
        int i = 0;
        
        while (i < n) {
            char c = s[i];
            int j = i;
            
            // 找到连续相同字符的子串
            while (j < n && s[j] == c) {
                j++;
            }
            
            int length = j - i;
            if (length < 3) {
                cout << -1 << endl;
                return 0;
            }
            
            vector<string> segments = splitSegment(s.substr(i, length));
            if (segments.empty()) {
                cout << -1 << endl;
                return 0;
            }
            
            for (const string& seg : segments) {
                result.push_back(seg);
            }
            
            i = j;
        }
        
        for (int i = 0; i < result.size(); i++) {
            cout << result[i];
            if (i < result.size() - 1) {
                cout << " ";
            }
        }
        cout << endl;
        
        return 0;
    }
    
    
    • 1

    科大讯飞2023提前批-2.小红的字符串切割

    信息

    ID
    86
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    1
    已通过
    1
    上传者