• P5698


    题面

    题意

    给你一份代码,仅包含 loop op break continue 四个命令,分别表示循环若干次,执行若干单位操作,跳出此层循环,跳过此层循环剩余部分。要你算出此代码的时间复杂度。

    分析

    我们可以对每一个 loopop 操作建一个点,点权即为该操作后面的 x 值,再按照他们的包含关系建一棵树。如果遇到 break,将此层 loop 对应的点的点权设置为 (1),再略过此层剩余部分的代码;如果遇到 continue,将此层剩余部分的代码略过即可。

    注意点上还有保存一个标记,表示该点是否存在实际贡献(就是该点对应的操作是不是 op),因为 loop 操作本身显然并不对答案存在贡献。

    代码

    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <vector>
    
    const int maxDep = 25;
    
    class Node {
       public:
        Node(Node* fa, int value, bool isLeaf) : father(fa), val(value), leaf(isLeaf) { return; }
    
        int val;                  //权值
        bool leaf;                //是否为叶子(是否需要算入复杂度)
        std::vector<Node> child;  //儿子节点
        Node* father;             //父亲指针
    };
    
    int stringToInt(const std::string& str) {
        int num = 0;
        for (std::string::const_iterator i = str.begin(); i != str.end(); i++) num = (num << 3) + (num << 1) + (*i ^ 48);
        return num;
    }
    void readUntilEnd(void) {
        std::string str;
        int cnt = 1;
        while (cnt) {
            std::cin >> str;
            if (str == "loop") cnt++;
            if (str == "end") cnt--;
        }
        return;
    }
    
    Node root(NULL, 0, false);  //根节点
    int answer[maxDep];
    
    void dfs(const Node& p, int x, int y) {
        if (p.leaf) {
            answer[x] += y;  //统计答案
            return;
        }
        for (std::vector<Node>::const_iterator i = p.child.begin(); i != p.child.end(); i++)
            (i->val == -1) ? dfs(*i, x + 1, y) : dfs(*i, x, y * i->val);  //根据此子节点权值更改参数
        return;
    }
    
    int main() {
        std::string cmd;
        Node* ptr = &root;
        while (true) {
            std::cin >> cmd;
            if (cmd == "op") {
                std::string x;
                std::cin >> x;
                ptr->child.push_back((Node){ptr, x == "n" ? -1 : stringToInt(x), true});
            } else if (cmd == "loop") {
                std::string x;
                std::cin >> x;
                if (x == "0") x = "n";  //数据问题,详见https://www.luogu.com.cn/discuss/show/271086
                ptr->child.push_back((Node){ptr, x == "n" ? -1 : stringToInt(x), false});
                ptr = &ptr->child.back();
            } else if (cmd == "break") {
                if (ptr == &root) continue;
                ptr->val = 1;  //由于循环至此必然结束,就相当于循环只运行了一遍
                ptr = ptr->father;
                readUntilEnd();
            } else if (cmd == "continue") {
                if (ptr == &root) continue;
                ptr = ptr->father;
                readUntilEnd();  //从这句话到结尾的所有话都可以无视
            } else if (cmd == "end") {
                if (ptr == &root) break;
                ptr = ptr->father;
            }
        }
        dfs(root, 0, 1);
        bool first = true;
        for (int i = maxDep - 1; ~i; i--)
            if (answer[i]) {
                if (!first) putchar('+');
                first = false;
                if (answer[i] != 1 || !i) printf("%d", answer[i]);
                if (i > 1)
                    printf("n^%d", i);
                else if (i == 1)
                    putchar('n');
            }
        if (first) putchar('0');
        puts("");
        return 0;
    }
    
  • 相关阅读:
    web前端导出csv文件
    eclipseGUI的可视化开发工具插件
    ionic2程序调试
    rxjs简单入门
    ionic2中使用自定义图标
    解决 Ionic 浏览器跨域问题
    VS2017 Cordova Ionic2 移动开发-环境搭建
    ionic环境搭建
    TypeScript学习笔记 (一)基础特性
    localStorage使用总结
  • 原文地址:https://www.cnblogs.com/macesuted/p/solution-P5698.html
Copyright © 2020-2023  润新知