1 条题解

  • 0
    @ 2025-8-24 21:26:39

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar wzmzmhk
    AFO

    搬运于2025-08-24 21:26:38,当前版本为作者最后更新于2021-07-21 16:49:18,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目传送门

    博客食用更佳


    此题C党的题解大部分都是用栈来完成的,那么本蒟蒻就来写一个与所有题解都不同的方法。

    大致思路:

    1. 首先读入一整行字符串。
    2. 进行特判,如果开头或末尾即为andor,或末尾为not,则直接输出error
    3. 找出所有的not,如果not后有orand,直接输出error;如果存在多个not的情况,则把每两个not删除。最后只剩一个或零个not,若剩一个not,则把后边的一个单词反转(即truefalse互换),并把not改为"   "(三个空格)。
    4. 找出所有的 and,如果and前面的第一个单词与后面的第一个单词都是true,那么把and以及任意一个true全部赋值为空格,例如,true and true变为true         (9个空格)。
    5. 找出所有的or,方法与and基本一致。
    6. 最后判断字母t与字母f的个数,如果二者都有或任意一者多余一个,则输出error,否则有1个t就输出true,有1个f就输出false

    注意:我们只需判断单词中的几个字母即可判断该单词为什么,因此不需要把整个单词分离判断。

    步骤1&&步骤2(输入并特判):

    //input
        getline(cin, s);
        int len = s.size();
        if (s[0] == 'a' || s[0] == 'o' || s[len - 1] == 'd' || s[len - 1] == 'r' || s[len - 1] == 't') {
            cout << "error";
            return 0;
        }
    

    步骤3(处理not):

    //not
        for (int i = 0; i < len; i++) {
            if (s[i] == 'n' && s[i + 1] == 'o') {
                int j = i + 4;
                while (s[j] == ' ') j++;
                if (s[j] == 't')
                    s[j] = 'f', s[j + 1] = 'a', s[j + 2] = 's', s[j + 3] = 'e', s[i] = s[i + 1] = s[i + 2] = ' ';
                    //因为"true"是4个字母,"false"是5个字母,而中间的"l"没有用,所以可以这样做
                else if (s[j] == 'f')
                    s[j] = 't', s[j + 1] = 'r', s[j + 2] = 'r', s[j + 3] = 'u', s[j + 4] = 'e', s[i] = s[i + 1] = s[i + 2] = ' ';
                    //道理同上
                else if (s[j] == 'n')
                    s[i] = s[i + 1] = s[i + 2] = s[j] = s[j + 1] = s[j + 2] = ' ';
                else {
                    cout << "error";
                    return 0;
                }
            }
        }
    

    步骤4(处理and):

    //and
        for (int i = 1; i < len; i++) {
            if (s[i] == 'a' && s[i + 1] == 'n') {
                int j = i - 2, k = i + 4;
                while (s[j] == ' ') j--;//此时j为and上一个字母的末尾下标
                while (s[k] == ' ') k++;//此时k为and后一个字母的首位下标
                if (s[k] == 'a' && s[k + 1] == 'n') {
                    cout << "error";
                    return 0;
                }//如果and后面还有and,就输出"error"
                while (s[j] != ' ' && j != 0) j--;//此时j为and上一个字母的首位下标
                while (s[k] != ' ' && k != len - 1) k++;//此时j为and上一个字母的末位下标
                if (j != 0)
                    j++;
                if (k != len - 1)
                    k--;
                bool flag1 = false, flag2 = false;
                if (s[j] == 't' && s[j + 1] == 'r')
                    flag1 = true;
                if (s[k] == 'e' && s[k - 1] == 'u')
                    flag2 = true;
                if (flag1 && flag2) {
                    s[j] = 't', s[j + 1] = 'r', s[j + 2] = 'u', s[j + 3] = 'e';
                    for (int l = j + 3 + 1; l <= k; l++)
                        s[l] = ' ';
                }
                else {
                    s[j] = 'f', s[j + 1] = 'a', s[j + 2] = 'l', s[j + 3] = 's', s[j + 4] = 'e';
                    for (int l = j + 4 + 1; l <= k; l++)
                        s[l] = ' ';
                }
            }
        }
    

    步骤5(处理or):

    此步骤与步骤4几乎一模一样,将步骤4稍微修改即可,这里留给读者自己思考。

    步骤6(输出):

    //output
        int t[200] = { 0 };//这里用了一个桶来统计字母出现的数量,t[s]表示为字母s出现的次数
        for (int i = 0; i < len; i++) {
            if (s[i] != ' ')
                t[s[i]]++;
        }
        if (t['t'] > 1 || t['f'] > 1 || (t['t'] >= 1 && t['f'] >= 1)) {
            cout << "error";
            return 0;
        }
        else if (t['t'] == 1)
            cout << "true";
        else
            cout << "false";
    
    • 1

    信息

    ID
    568
    时间
    1000ms
    内存
    128MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者