题解:B4353 [信息与未来 2025] 程序套娃(暂无 SPJ)

· · 题解

话说信息与未来的题目是真有意思。
难以置信的是我居然在考场上搞定了这道题。

思路

这道题呢我使用的方法是一层一层加,也就是说从满足p_{i+1}.cpp要求的推导到满足p_i.cpp要求的。

推导方式

每一次从推导p_{i+1}.cpp推导到p_i.cpp方法就是:

1、先把在p_{i+1}.cpp中的每一个\\变成\\\\,还要把\"变成\\\"

因为c、c++输出时为了区分,如果想要输出"\时需要输出\"\\

2、在修改后的p_{i+1}.cpp的每一行套上cout << \"\" << endl;"

这里之所以使用\"而非"是因为我们输出p_{i-1}.cpp的时候会吃掉那个\,这样就可以在运行到p_i的时候只剩"了。

3、在进一步修改后的p_{i+1}.cpp 的前面加上

#include <iostream>
using namespace std;
int main() {

后面加上

return 0;
}

这样就完成了p_i.cpp

注意点

还要注意的是:

1、最开始时我建议不要在数字两边输出"。 虽然我不知道能不能。
2、如果用的是我的方法的话,最后一次推导到p_1.cpp的时候不需要把每一个\\变成\\\\,也不需要把\"变成\\\",更不要在最后一次的时候cout后面还用\",直接用"就好了。
3、在将\"变成字符串拼接到代码上去时,需要写成"\\\""
4、存放代码时不可在二维数组的开头几行存,因为我们推导时需要在每次在顶上加上3行。

代码

考场AC代码:(注释是后加的)(freopen似乎删掉了)

#include <bits/stdc++.h>
using namespace std;
map<int, string> s; // 用于存放当前.cpp程序,这边我使用的是map,数组应该也可以。
string nts(int k) // 数字转字符串,这样可以使用STL string直接拼接。
{
    string s;
    while (k)
    {
        s = (char)(k % 10 + '0') + s;
        k /= 10;
    }
    return s;
}
pair<int, int> kkk(int mn, int mx, int i) // 推导,方法看上面。mn的意思是当前程序第一行在s中的行下标,mx的意思是最后一行程序在s中的行下标。i好像没有用(比赛时脑子抽了)
{
    for (map<int, string>::iterator it  = s.begin(); it != s.end(); it++)
    {
        string t; 用于存放第一步过后该行代码。
        for (int i = 0; i < s[it->first].size(); i++)
        {
            // 将\\改成\\\\,\"改成\\\"。
            if (s[it->first][i] == '\\')
            {
                t += "\\\\";
            }
            else if (s[it->first][i] == '\"')
            {
                t += "\\\"";
            }
            else
            {
                t += s[it->first][i];
            }
        }
        s[it->first] = "cout << \\\"" + t + "\\\" << endl;"; // 第二步,前后加上cout << \" 和 \" << endl;" 注意一下注意点3
    }
    // 第3部,前后加上头文件,主函数,大括号,return 0 等。
    s[mn - 3] = "#include <iostream>"; 
    s[mn - 2] = "using namespace std;";
    s[mn - 1] = "int main() {";
    s[mx + 1] = "return 0;";
    s[mx + 2] = "}";
    return { mn - 3, mx + 2 };
}
int main()
{
    int n, k;
    cin >> n >> k;
    if (n == 1)
    {
        cout << k << endl;
        return 0;
    }
    // 注意一下注意点4
    // 数字有点臭,不喜勿喷
    s[11451] = "#include <iostream>";
    s[11452] = "using namespace std;";
    s[11453] = "int main() { ";
    s[11454] = "cout << " + nts(k) + " << endl;"; // 注意一下注意点1
    s[11455] = "return 0;";
    s[11456] = "}";
    if (n == 2)
    {
        for (map<int, string>::iterator it = s.begin(); it != s.end(); it++)
        {
            cout << s[it->first] << endl;
        }
        return 0;
    }
    int mn = 11451;
    int mx = 11456;
    for (int i = 2; i < n - 1; i++)
    {
        // 推导
        pair<int, int> pii = kkk(mn, mx, i - 2);
        // 更新mn 和 mx
        mn = pii.first; 
        mx = pii.second;
    }
    for (map<int, string>::iterator it = s.begin(); it != s.end(); it++)
    {
        s[it->first] = "cout << \"" + s[it->first] + "\" << endl;"; // 注意一下注意点4
    }
    s[mn - 3] = "#include <iostream>";
    s[mn - 2] = "using namespace std;";
    s[mn - 1] = "int main() {";
    s[mx + 1] = "return 0;";
    s[mx + 2] = "}";
   // 输出,也可以输出mn到mx,但是如果输出mn到mx的话最后别忘了在更新一下哦
    for (map<int, string>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << s[it->first] << endl;
    }
    return 0;
}

结语

非常感谢各位大佬能够看完该蒟蒻的题解!^v^
这是我第一次在洛谷写公开题解,如果发现有什么错误或者可以改进的地方,一定要私信告诉我!
管理员辛苦了,可以让我一遍过吗?
最后,写题解不易,给个赞吧!谢谢!