【每日一题】Problem 174B. File List

发布时间 2023-06-14 20:05:02作者: HelloEricy

原题

解决思路

纯模拟,比较文件名长度是否合规,文件格式+下一个文件名长度是否合规

误区
  1. 文件名的长度要和文件格式+下一个文件名的长度分开判断
    • 更新左端点和每次迭代开始先判断的方式解决该问题
  2. 最后一个 '.' 后的文件格式需要特殊处理
    • 在循环结束后与 '.' 不存在的情况共同处理
  3. vector 中的元素类型如果是 string,那么复制字符串的过程相当耗时
    • vector 中保留文件名的右端点,打印时以\([l, r]\)为范围循环打印每个字符
  4. std::endl 不仅有换行的功能,同时也会刷新 io 流,该操作也十分耗时

    Inserts a newline character into the output sequence os and flushes it as if by calling os.put(os.widen('\n')) followed by os.flush().

    • 使用 std::cout << "\n" 替换 std::endl
#include <bits/stdc++.h>
#define ull unsigned long long
int main() {
    std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
    std::string s; std::cin >> s;
    ull l, r, len, pos, npos;
    l = r = 0, pos = npos = std::string::npos;
    std::vector<ull> fs;
    bool ok = true;

    npos = s.find('.', pos + 1);
    while (npos != std::string::npos) {
        if (npos == l || npos - l > 8) {
            // '.' 为下一个文件名的开头或文件头太长,格式错误
            ok = false;
            break;
        }

        // 计算文件格式与下一个文件头
        pos = npos; // 更新 '.' 坐标
        npos = s.find('.', pos + 1);
        if (npos != std::string::npos) {
            len = npos - pos - 1;
            if (len > 11 || len < 2) {
                ok = false;
                break;
            }

            if (len > 8) r = pos + len - 8;
            else r = pos + 1;
            fs.push_back(r);
            l = r + 1;
        }
    }

    // 判断最后一个 '.' 后的字符串是否符合要求
    if (pos == std::string::npos) {
        // 文件名中不存在 '.'
        ok = false;
    } else {
        len = s.size() - pos - 1;
        if (len <= 0 || len > 3) {
            // 最后一个 '.' 后没有字符或太多,格式错误
            ok = false;
        } else {
            fs.push_back(s.size() - 1);
        }
    }

    if (!ok) std::cout << "NO\n";
    else {
        std::cout << "YES\n";
        int i = 0;
        for (auto p : fs) {
            while (i <= p) std::cout << s[i++];
            std::cout << "\n";
        }
    }
    return 0;
}

总结

模拟的时候思路还是不够清晰,导致常常是面向测试结果编程