洛谷B4069 [GESP202412 四级] 字符排序

原理

  1. 字符串有效性检查
    每个输入的字符串必须内部字符按非降序排列,否则整个测试用例直接输出 0
  2. 排序规则
    • 优先按字符串的首字符升序排列。
    • 若首字符相同,则按字符串的最后一个字符升序排列。
  3. 相邻条件验证
    排序后需确保每个字符串的最后一个字符不大于下一个字符串的首字符。若全部满足,输出 1;否则输出 0

步骤

  1. 输入处理
    读取测试用例数 T,对每个测试用例:
    • 读取 n 个字符串。
    • 检查每个字符串是否非降序排列。
  2. 字符串有效性判断
    若存在非法字符串,直接输出 0,跳过后续处理。
  3. 字符串排序
    按首字符和尾字符的升序规则排序。
  4. 相邻条件检查
    遍历排序后的字符串数组,验证每个字符串的最后一个字符是否小于等于下一个字符串的首字符。
  5. 输出结果
    根据验证结果输出 1 或 0

图示法示例(输入:["app", "abc", "def"]

1. 检查字符串有效性:
   - "app":有效(a ≤ p ≤ p)
   - "abc":有效(a ≤ b ≤ c)
   - "def":有效(d ≤ e ≤ f)

2. 排序:
   - 首字符均为 "a" 的 "app" 和 "abc" 按尾字符排序:
     - "abc"(尾字符 `c`)排在 "app"(尾字符 `p`)前。
   - 排序后顺序:["abc", "app", "def"]

3. 相邻检查:
   - "abc" 的尾字符 `c` > "app" 的首字符 `a` → 不满足条件。
   
结果:输出 0

代码程序及关键行注释

#include 
#include 
#include 
#include 

using namespace std;

// 检查字符串是否为非降序排列
bool is_Valid(const string &s) {
    for (int i = 0; i < s.size() - 1; i++) {
        if (s[i] > s[i + 1]) {
            return false;
        }
    }
    return true;
}

// 排序规则:首字符升序,次尾字符升序
bool compare(const string &a, const string &b) {
    if (a[0] != b[0]) {
        return a[0] < b[0]; // 首字符升序
    } else {
        return a.back() < b.back(); // 尾字符升序(首字符相同)
    }
}

int main() {
    int T;
    cin >> T;
    for (int i = 0; i < T; i++) {
        int n;
        cin >> n;
        vector A(n);
        bool valid = true;
        
        // 读取并检查字符串有效性
        for (int j = 0; j < n; j++) {
            cin >> A[j];
            if (!is_Valid(A[j])) {
                valid = false;
            }
        }
        
        if (!valid) {
            cout << 0 << endl;
            continue; // 存在无效字符串,跳过后续处理
        }
        
        sort(A.begin(), A.end(), compare); // 按规则排序
        
        // 检查相邻字符串的尾首条件
        bool flag = true;
        for (int j = 0; j < n - 1; j++) {
            if (A[j].back() > A[j + 1][0]) {
                flag = false;
                break;
            }
        }
        
        cout << (flag ? 1 : 0) << endl;
    }
    return 0;
}

时间复杂度

  1. 字符串有效性检查
    • 单次测试用例:O(n * m),其中 m 为字符串平均长度。
  2. 排序
    • 单次测试用例:O(n log n),比较操作时间复杂度为 O(1)
  3. 相邻条件检查
    • 单次测试用例:O(n)
  4. 总复杂度
    • 对于 T 个测试用例:O(T * (n * m + n log n))

总结

  1. 核心思想
    • 先确保所有字符串内部有序,再通过特定排序规则尝试满足相邻条件。
  2. 适用场景
    • 适用于字符串长度较短且测试规模较小的场景。
  3. 潜在问题
    • 排序规则可能无法覆盖所有可能的合法排列,导致误判。
  4. 优化方向
    • 若题目允许任意排列,需更复杂的算法(如拓扑排序或贪心策略),但时间复杂度较高。当前实现假设特定排序规则能覆盖合法情况。

你可能感兴趣的:(编程算法提高(c++),算法,c++)