1 条题解

  • 0
    @ 2025-8-24 22:44:08

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Infinite_Eternity
    『放肆梦一场,谁说永夜中照不进天光,当乌云散去,自有漫天繁星』

    搬运于2025-08-24 22:44:08,当前版本为作者最后更新于2022-12-24 17:38:04,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    梦幻 | Reopening of Dream\large\textbf{梦幻 | Reopening of Dream}

    按题意模拟即可。

    由于不知道每个 <title> 的长度为多少,以及为了避免忘记清空 char 数组,推荐使用 string 类型。

    string title[4],read,write;
    

    其中,title\text{title} 是每道题目的名称,read\text{read} 指选手的 freopen("<title>.in","r",stdin); 语句,write\text{write} 指选手的 freopen("<title>.out","w",stdout); 语句。

    我们将普通人作为 type 1\text{type 1},将乐子人作为 type 2\text{type 2},将见祖宗人作为 type 3\text{type 3}。(原因会在下文中解释)

    • 对于 type 1\text{type 1},我们需要使得 read\text{read}write\text{write} 皆与正确语句一模一样:(由于字符串可以拼接的特性,我们可以用 + 进行连接。其中,\ 是转义符。)
    if ((read == "freopen(\"" + title[j] + ".in\",\"r\",stdin);") && (write == "freopen(\"" + title[j] + ".out\",\"w\",stdout);"))
    	each_type = 1;
    

    在讲解 type 3\text{type 3} 之前,我们先补充一下 substr()\text{substr()} 函数的用法:

    假设 string s = "E_Space_is_amazing";

    • string sub1 = s.substr(11) 表示:从下标为 1111 的字符开始,一直取到结尾,则 sub1 = "amazing"

    • string sub2 = s.substr(11,3)表示:从下标为 1111 的字符开始,截取长度为 33 的子串,则 sub2 = "ama"

    特别地:

    • 若开始字符的下标超过了 s.length()s.\text{length()},则 substr()\text{substr()} 函数会返回 terminate called after throwing an instance of 'std::out_of_range'
    • 若开始字符的下标与截取长度的和超过了 s.length()s.\text{length()},则 substr()\text{substr()} 函数将截取到 string s 的末尾后自动停止。

    • 对于 type 3\text{type 3},我们需要使得 read\text{read}write\text{write}至少有一句//freopen( 开头,以 ); 结尾:(切记,需要与题目描述一致,不可只判断是否以 // 开头)
    else if ((read.substr(0, 10) == "//freopen(") && (read.substr(read.length()-2) == ");") || 
            (write.substr(0, 10) == "//freopen(") && (write.substr(write.length()-2) == ");"))
    	each_type = 3;
    

    值得一提的是,注意到在判断语句 (read.substr(read.length()-2) == ");") 中:当 read.length() < 2 时,会引起 Runtime Error;但是当 read.length() < 2 时,(read.substr(0, 10) == "//freopen(") 必然不成立,构成 && 短路,于是不会 Runtime Error。

    最后,我们来解释一下本题的优先级,同时回答上文的问题。

    • 在同时出现普通行为和乐子行为时,我们优先考虑乐子行为,即:type 1 < type 2\text{type 1 < type 2}
    • 在同时出现普通行为和见祖宗行为时,我们优先考虑见祖宗行为,即:type 1 < type 3\text{type 1 < type 3}
    • 在同时出现乐子行为和见祖宗行为时,我们优先考虑见祖宗行为,即:type 2 < type 3\text{type 2 < type 3}

    综上,type 1 < type 2 < type 3\text{type 1 < type 2 < type 3}。这样,代码的实现便容易了许多。

    参考代码:

    #include <bits/stdc++.h>
    using namespace std;
    int T,n,m;
    string title[4],read,write;
    inline int max(int a,int b)
    {
        return (a>b) ? a : b;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(nullptr),cout.tie(nullptr);
        cin >> T >> n >> m;
        for (register int i=0; i<m; ++i)
        {
            cin >> title[i];
        }
        for (register int i=0; i<n; ++i)
        {
            int type=1;
            for (register int j=0; j<m; ++j)
            {
                int each_type=2;
                cin >> read >> write;
                if ((read == "freopen(\"" + title[j] + ".in\",\"r\",stdin);") && (write == "freopen(\"" + title[j] + ".out\",\"w\",stdout);"))
                    each_type = 1;
                else if ((read.substr(0, 10) == "//freopen(") && (read.substr(read.length()-2) == ");") || (write.substr(0, 10) == "//freopen(") && (write.substr(write.length()-2) == ");"))
                    each_type = 3;
                type=max(type,each_type);
            }
            if (type == 1)
                puts("PION2202 RP++.");
            else if (type == 3)
                puts("Wrong file operation takes you to your ancestors along with your 3 years' efforts on OI.");
            else
                puts("Good luck and have fun.");
        }
        return 0;
    }
    

    Ps. 感谢 Cloud_yxsubstr()\text{substr()} 函数的用法的补充。

    • 1

    信息

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